Selaa lähdekoodia

1.招聘申请插件优化;
2.出差单时长扩展,排除非班次时长
3.出差核算时长扩展,排除非班次时长且计算出差期间的每一天

Tyx 3 viikkoa sitten
vanhempi
säilyke
0f7fa2fb98

+ 10 - 11
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/tsrsc/plugin/form/YearCrApplyFormPlugin.java

@@ -550,21 +550,20 @@ public class YearCrApplyFormPlugin extends AbstractBillPlugIn implements BeforeF
                 int[] rows2 = treeEntryEntity2.getSelectRows();
                 DynamicObject nckdRecruitcompany2 = (DynamicObject)this.getModel().getValue("org");
 
-
-
-                QFilter qFilter1 = new QFilter("adminorg.number", QCP.like, nckdRecruitcompany2.getString("number") + "%");
+                //QFilter qFilter1 = new QFilter("adminorg.number", QCP.like, nckdRecruitcompany2.getString("number") + "%");
                 DynamicObject nckdRecruitorg = (DynamicObject)this.getModel().getValue("nckd_recruitorg", rows2[0]);
                 if(ObjectUtils.isNotEmpty(nckdRecruitorg)){
-                    qFilter1.and("adminorg.id", QCP.equals, nckdRecruitorg.getPkValue());
+                    QFilter qFilter1 = new QFilter("adminorg.id", QCP.equals, nckdRecruitorg.getPkValue());
+                    showParameter3.getListFilterParameter().setFilter(qFilter1);
                 }
-                showParameter3.getListFilterParameter().setFilter(qFilter1);
-                break;
-            case "org":
-                ListShowParameter showParameter4 = (ListShowParameter)e.getFormShowParameter();
-                // 去除部门
-                QFilter qFilter4 = new QFilter("orgpattern.number", "in", COMPANY_LIST2);
-                showParameter4.getListFilterParameter().setFilter(qFilter4);
+
                 break;
+//            case "org":
+//                ListShowParameter showParameter4 = (ListShowParameter)e.getFormShowParameter();
+//                // 去除部门
+//                QFilter qFilter4 = new QFilter("orgpattern.number", "in", COMPANY_LIST2);
+//                showParameter4.getListFilterParameter().setFilter(qFilter4);
+//                break;
             default:
                 break;
         }

+ 13 - 12
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/tsrsc/plugin/form/YearCrApplyPlanFormPlugin.java

@@ -148,16 +148,16 @@ public class YearCrApplyPlanFormPlugin extends AbstractBillPlugIn implements Bef
     @Override
     public void beforeF7Select(BeforeF7SelectEvent e) {
         String fieldKey = e.getProperty().getName();
-        switch (fieldKey) {
-            case "org":
-                ListShowParameter showParameter4 = (ListShowParameter) e.getFormShowParameter();
-                // 去除部门
-                QFilter qFilter4 = new QFilter("orgpattern.number", "in", COMPANY_LIST2);
-                showParameter4.getListFilterParameter().setFilter(qFilter4);
-                break;
-            default:
-                break;
-        }
+//        switch (fieldKey) {
+//            case "org":
+//                ListShowParameter showParameter4 = (ListShowParameter) e.getFormShowParameter();
+//                // 去除部门
+//                QFilter qFilter4 = new QFilter("orgpattern.number", "in", COMPANY_LIST2);
+//                showParameter4.getListFilterParameter().setFilter(qFilter4);
+//                break;
+//            default:
+//                break;
+//        }
     }
 
 
@@ -176,6 +176,7 @@ public class YearCrApplyPlanFormPlugin extends AbstractBillPlugIn implements Bef
         super.beforeItemClick(evt);
         String key = evt.getItemKey();
         //监听分录刷新招聘申请按钮
+        //携带年度招聘申请的数据到本单
         if (key.equals("nckd_advconbaritemap1")) {
             DynamicObjectCollection entryentity = this.getModel().getDataEntity(true).getDynamicObjectCollection("entryentity");
             // 获取年度
@@ -201,7 +202,7 @@ public class YearCrApplyPlanFormPlugin extends AbstractBillPlugIn implements Bef
                 summary.or("entryentity.nckd_casreplanid", QCP.equals, pkValue);
             }
             qFilter.and(summary);
-            // 年度招聘计划数据
+            // 年度招聘申请数据
             DynamicObject[] loads = BusinessDataServiceHelper.load("nckd_yearapply", "id,org,org.id,billstatus,entryentity,entryentity.nckd_recruitorg," +
                     "entryentity.nckd_recruitpost,entryentity.nckd_recruitnum,entryentity.nckd_majortype,entryentity.nckd_qualifications," +
                     "entryentity.nckd_payrange,entryentity.nckd_employcategory,entryentity.nckd_recruittype,nckd_year,entryentity.nckd_summary," +
@@ -212,7 +213,7 @@ public class YearCrApplyPlanFormPlugin extends AbstractBillPlugIn implements Bef
             }
             ORM orm = ORM.create();
             for (DynamicObject dynamicObject : loads) {
-                // 获取招聘计划的下级分录
+                // 获取招聘申请的下级分录
                 DynamicObjectCollection entryentity1 = dynamicObject.getDynamicObjectCollection("entryentity");
                 if (ObjectUtils.isEmpty(entryentity1)) {
                     continue;

+ 140 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/wtc/wtam/explugin/TpApplyTimeCalculateExtPluginEx.java

@@ -0,0 +1,140 @@
+package nckd.jimin.jyyy.hr.wtc.wtam.explugin;
+
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.sdk.wtc.wtam.business.applytime.TpApplyTimeCalculateEvent;
+import kd.sdk.wtc.wtam.business.applytime.TpApplyTimeCalculateExtPlugin;
+import kd.sdk.wtc.wtbs.common.dto.shift.ShiftDetailDto;
+import kd.sdk.wtc.wtbs.common.dto.shift.ShiftDto;
+import kd.wtc.wtbs.business.util.ShiftParseUtil;
+import kd.wtc.wtbs.common.model.evaluation.ShiftDetail;
+import kd.wtc.wtbs.common.model.shift.RefDateType;
+import kd.wtc.wtbs.common.util.WTCDateUtils;
+import kd.wtc.wtbs.common.util.third.util.DateUtils;
+import kd.wtc.wtbs.common.util.third.util.StringUtils;
+import kd.wtc.wtes.business.model.shift.OutWorkType;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Description      :出差申请时长计算扩展,处理跨天逻辑,去除休息时长
+ * @author Tyx
+ * @date  2025/5/16
+ * 标识 nckd_casrecrapply
+ */
+
+
+public class TpApplyTimeCalculateExtPluginEx implements TpApplyTimeCalculateExtPlugin {
+    private static Log log = LogFactory.getLog(TpApplyTimeCalculateExtPluginEx.class);
+    @Override
+    public void onCalculateApplyTime(TpApplyTimeCalculateEvent tpApplyTimeCalculateEvent) {
+        log.info("开始执行出差单申请时长计算扩展:");
+        //时长类型,非时分的情况下直接返回
+        String unit = tpApplyTimeCalculateEvent.getEntryDy().getString("unit");
+        if(!"B".equals(unit))
+            return;
+        Date startDate = tpApplyTimeCalculateEvent.getEntryDy().getDate("startdate");       //分录出差开始时间
+        LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();   //分录出差开始时间
+        Date endDate = tpApplyTimeCalculateEvent.getEntryDy().getDate("enddate");         //分录出差结束时间
+        LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();       //分录出差结束时间
+        //String startDateStr = sdf.format(startDate);
+        //String endDateStr = sdf.format(endDate);
+        //排班信息 key:日期,value:shiftDto
+        Map shiftMap = tpApplyTimeCalculateEvent.getShiftMap();
+
+        //默认班次时长
+        ShiftDto defaultShift = (ShiftDto) shiftMap.get(startLocalDate);
+        BigDecimal defaultDayHours = defaultShift.getShiftMiddleRuleDto().getAlldayhour();
+        BigDecimal DECIMAL_ONE_HOUR_SECONDS =  new BigDecimal(3600L);
+        BigDecimal defaultDayHoursLong = defaultDayHours.multiply(DECIMAL_ONE_HOUR_SECONDS);
+        log.info("默认班次时长:{},默认班次时长(秒):{}", defaultDayHours, defaultDayHoursLong);
+        //相差天数
+        long days = ChronoUnit.DAYS.between(startLocalDate, endLocalDate);
+
+        //计算时长
+        BigDecimal valHours = BigDecimal.ZERO;
+        BigDecimal sumHours = BigDecimal.ZERO;
+        BigDecimal sumDays = BigDecimal.ZERO;
+        for (int i = 0 ; i <= days; i++) {
+            // i == 0时,为出差开始这天,单独处理时长; i == days为出差结束这天,单独处理时长
+            if(i == 0 || i == days) {
+                Instant instant = null;
+                if(i == 0) {
+                    instant = startLocalDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
+                }
+                else if (i == days) {
+                    instant = endLocalDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
+                }
+                ShiftDto shiftDto = (ShiftDto) shiftMap.get(startLocalDate);
+                BigDecimal calHours = dealDayApplyTime(startDate, endDate, shiftDto, Date.from(instant));
+                valHours = valHours.add(calHours);
+                log.info("{} : 计算时长为 : {}", Date.from(instant), valHours);
+            }
+            // i <> 0 && i <> days时,为中间段日期,默认按班次时长计算
+            if(i != 0 && i != days) {
+                valHours = valHours.add(defaultDayHoursLong);
+            }
+        }
+        // 转换成小时
+        sumHours = valHours.divide(DECIMAL_ONE_HOUR_SECONDS, 6, RoundingMode.HALF_UP);
+        // 转换成天数
+        sumDays = sumHours.divide(defaultDayHours, 6, RoundingMode.HALF_UP);
+        // 回写结果
+        tpApplyTimeCalculateEvent.getResult().setValHour(sumHours);
+        tpApplyTimeCalculateEvent.getResult().setValDay(sumDays);
+    }
+
+    /**
+     * 根据班次计算每天的出差时长
+     * @param startDate  出差开始时间
+     * @param endDate    出差结束时间
+     * @param shiftDto   班次信息
+     * @param rosterDate 班次时间
+     */
+    public BigDecimal dealDayApplyTime (Date startDate, Date endDate, ShiftDto shiftDto, Date rosterDate) {
+        List<ShiftDetailDto> shiftList = shiftDto.getShiftDetailDtoList();
+        BigDecimal sumHours = BigDecimal.ZERO;
+        for(ShiftDetailDto detailDto : shiftList) {
+            if(detailDto.getOutWorkType().equals(OutWorkType.BREAK.code))
+                continue;
+            Date prevEndDateTime = getRosterStartDate(detailDto, rosterDate);
+            Date detailEndDate = getRosterDetailEndDate(detailDto, rosterDate);
+            long shiftDetailInsectionTimes = WTCDateUtils.getDateInsectionTimes(startDate, endDate, prevEndDateTime, detailEndDate);
+            sumHours = sumHours.add(BigDecimal.valueOf(shiftDetailInsectionTimes));
+        }
+        return sumHours;
+    }
+
+    public static Date getRosterStartDate(ShiftDetailDto detail, Date rosterDate) {
+        Date date = rosterDate;
+        String refStartDay = detail.getRefStartDay();
+        if (StringUtils.equals(RefDateType.NEXTDAY.code, refStartDay)) {
+            date = DateUtils.addDays(rosterDate, 1);
+        }
+
+        int shiftStartDate = detail.getShiftStartDate();
+        date = WTCDateUtils.getDate(date, shiftStartDate);
+        return date;
+    }
+
+    public static Date getRosterDetailEndDate(ShiftDetailDto shiftDetail, Date rosterDate) {
+        Date rosterShiftEndDate = WTCDateUtils.getDate(rosterDate, shiftDetail.getShiftEndDate());
+        if (StringUtils.equals(shiftDetail.getRefEndDay(), RefDateType.NEXTDAY.code)) {
+            rosterShiftEndDate = DateUtils.addDays(rosterShiftEndDate, 1);
+        }
+
+        return rosterShiftEndDate;
+    }
+
+
+}

+ 139 - 0
code/jyyy/nckd-jimin-jyyy-hr/src/main/java/nckd/jimin/jyyy/hr/wtc/wtam/explugin/TvlBillTimeBucketSplitExtPluginEx.java

@@ -0,0 +1,139 @@
+package nckd.jimin.jyyy.hr.wtc.wtam.explugin;
+
+import com.google.common.collect.Lists;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.util.Set;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.sdk.wtc.wtes.business.tie.init.bill.TvlBillTimeBucketSplitEvent;
+import kd.sdk.wtc.wtes.business.tie.init.bill.TvlBillTimeBucketSplitExtPlugin;
+import kd.sdk.wtc.wtes.business.tie.model.roster.RosterExt;
+import kd.sdk.wtc.wtes.business.tie.model.roster.ShiftSpecExt;
+import kd.sdk.wtc.wtes.business.tie.model.roster.ShiftTableSingleExt;
+import kd.sdk.wtc.wtes.business.tie.model.timebucket.AttBillTimeBucketExt;
+import org.apache.curator.shaded.com.google.common.collect.Sets;
+/**
+ * Description      :出差核算时长计算扩展,处理跨天逻辑,去除休息时长
+ * 反编译标品 kd.sdk.wtc.wtes.business.tie.init.bill.TvlBillTimeBucketSplitExtPluginDemo
+ * @author Tyx
+ * @date  2025/5/16
+ * 标识 nckd_casrecrapply
+ */
+
+public class TvlBillTimeBucketSplitExtPluginEx implements TvlBillTimeBucketSplitExtPlugin {
+
+    private static Log log = LogFactory.getLog(TvlBillTimeBucketSplitExtPluginEx.class);
+
+    @Override
+    public void splitVaBillTimeBucket(TvlBillTimeBucketSplitEvent tvlBillTimeBucketSplitEvent) {
+        log.info("出差核算时长二开开始");
+        Set<AttBillTimeBucketExt> timeBucketExtSetRes = Sets.newHashSet();
+        for (AttBillTimeBucketExt billTimeBucketExt : tvlBillTimeBucketSplitEvent.getAttBillTimeBucketExtList()) {
+            DynamicObject entryRowDy = billTimeBucketExt.getEntryRowDy();
+            ShiftTableSingleExt shiftTableSingleExt = tvlBillTimeBucketSplitEvent.getShiftTableExt().shiftTableSingle(billTimeBucketExt.getAttPersonId());
+            if (entryRowDy != null && "3".equals(entryRowDy.getString("startmethod"))) {
+                LocalDateTime startDate = billTimeBucketExt.getStartTime();
+                LocalDateTime endDate = billTimeBucketExt.getEndTime();
+                // 2025-05-20 Tyx 如果endDate > shiftendDate 则取shiftendDate
+                LocalDate shiftstartDate = tvlBillTimeBucketSplitEvent.getStartDate();
+                LocalDate shiftendDate = tvlBillTimeBucketSplitEvent.getEndDate();
+                Set<AttBillTimeBucketExt> timeBucketExtSet = Sets.newHashSet();
+                while (shiftstartDate.compareTo((ChronoLocalDate)shiftendDate) <= 0) {
+                    LocalDateTime shiftStart = this.getshiftStartDateTime(shiftstartDate, shiftTableSingleExt);
+                    LocalDateTime shiftEnd = this.getshiftEndDateTime(shiftstartDate, shiftTableSingleExt);
+                    LocalDateTime shiftStartNext = this.getshiftStartDateTime(shiftstartDate.plusDays(1L), shiftTableSingleExt);
+                    LocalDateTime start = (startDate.compareTo((ChronoLocalDateTime<?>)shiftStart) > 0) ? startDate : shiftStart;
+                    LocalDateTime end = (endDate.compareTo((ChronoLocalDateTime<?>)shiftStartNext) < 0) ? endDate : shiftEnd;
+                    if (start.compareTo((ChronoLocalDateTime<?>)end) < 0) {
+                        timeBucketExtSet.add(billTimeBucketExt.newInstanceResetTime(billTimeBucketExt, shiftstartDate, start, end));
+                    }
+                    shiftstartDate = shiftstartDate.plusDays(1L);
+                }
+                if (timeBucketExtSet.isEmpty()) {
+                    timeBucketExtSet.add(billTimeBucketExt);
+                }
+                timeBucketExtSetRes.addAll(timeBucketExtSet);
+            }
+        }
+        tvlBillTimeBucketSplitEvent.setAttBillTimeBucketExtList(Lists.newArrayList((Iterable)timeBucketExtSetRes));
+    }
+
+    private LocalDateTime getshiftStartDateTime(final LocalDate localDate, final ShiftTableSingleExt shiftTableSingleExt) {
+        final RosterExt rosterExt = shiftTableSingleExt.getRoster(localDate);
+        final ShiftSpecExt shiftSpecExt = rosterExt.getShiftSpec();
+        if (shiftSpecExt.isOffNonPlan()) {
+            return this.getshiftStartDateTimeNoPlan(localDate, shiftTableSingleExt);
+        }
+        return this.getshiftStartDateTimeHasPlan(localDate, shiftTableSingleExt);
+    }
+
+    private LocalDateTime getshiftStartDateTimeNoPlan(final LocalDate localDate, final ShiftTableSingleExt shiftTableSingleExt) {
+        final RosterExt rosterExt = shiftTableSingleExt.getRoster(localDate);
+        final ShiftSpecExt shiftSpecExt = rosterExt.getShiftSpec();
+        LocalDateTime shiftStart = localDate.atStartOfDay();
+        if (shiftSpecExt.isOffNonPlan()) {
+            final RosterExt preRosterExt = shiftTableSingleExt.getRoster(localDate.plusDays(-1L));
+            final ShiftSpecExt preShiftSpecExt = preRosterExt.getShiftSpec();
+            if (!preShiftSpecExt.isOffNonPlan()) {
+                final LocalDateTime preShiftEndDateTime = this.getshiftEndDateTime(localDate.plusDays(-1L), shiftTableSingleExt);
+                shiftStart = ((shiftStart.compareTo((ChronoLocalDateTime<?>)preShiftEndDateTime) > 0) ? shiftStart : preShiftEndDateTime);
+            }
+        }
+        return shiftStart;
+    }
+
+    private LocalDateTime getshiftStartDateTimeHasPlan(final LocalDate localDate, final ShiftTableSingleExt shiftTableSingleExt) {
+        final RosterExt rosterExt = shiftTableSingleExt.getRoster(localDate);
+        final ShiftSpecExt shiftSpecExt = rosterExt.getShiftSpec();
+        LocalDateTime shiftStart = localDate.atStartOfDay();
+        if (shiftSpecExt.isOffNonPlan()) {
+            return shiftStart;
+        }
+        if (RefDateType.TODAY.code.equals(shiftSpecExt.getFirstRefDateType())) {
+            shiftStart = LocalDateTime.of(localDate, shiftSpecExt.getEarliestShiftTime());
+        }
+        else if (RefDateType.NEXTDAY.code.equals(shiftSpecExt.getFirstRefDateType())) {
+            shiftStart = LocalDateTime.of(localDate.plusDays(1L), shiftSpecExt.getEarliestShiftTime());
+        }
+        else if (RefDateType.LASTDAY.code.equals(shiftSpecExt.getFirstRefDateType())) {
+            shiftStart = LocalDateTime.of(localDate.plusDays(-1L), shiftSpecExt.getEarliestShiftTime());
+        }
+        return shiftStart;
+    }
+
+    private LocalDateTime getshiftEndDateTime(final LocalDate localDate, final ShiftTableSingleExt shiftTableSingleExt) {
+        final RosterExt rosterExt = shiftTableSingleExt.getRoster(localDate);
+        final ShiftSpecExt shiftSpecExt = rosterExt.getShiftSpec();
+        LocalDateTime shiftEnd = localDate.plusDays(1L).atStartOfDay();
+        if (shiftSpecExt.isOffNonPlan()) {
+            return shiftEnd;
+        }
+        if (RefDateType.TODAY.code.equals(shiftSpecExt.getLastRefDateType())) {
+            shiftEnd = LocalDateTime.of(localDate, shiftSpecExt.getLastShiftTime());
+        }
+        else if (RefDateType.NEXTDAY.code.equals(shiftSpecExt.getLastRefDateType())) {
+            shiftEnd = LocalDateTime.of(localDate.plusDays(1L), shiftSpecExt.getLastShiftTime());
+        }
+        else if (RefDateType.LASTDAY.code.equals(shiftSpecExt.getLastRefDateType())) {
+            shiftEnd = LocalDateTime.of(localDate.plusDays(-1L), shiftSpecExt.getLastShiftTime());
+        }
+        return shiftEnd;
+    }
+
+    enum RefDateType
+    {
+        TODAY("D"),
+        NEXTDAY("C"),
+        LASTDAY("Q");
+
+        public final String code;
+
+        private RefDateType(final String code) {
+            this.code = code;
+        }
+    }
+}