Преглед на файлове

feat(common): 添加用工关系类型常量和日期工具方法

- 在FormConstant中新增LABORRELTYPE常量
- 在DateUtil中添加addMonths、beginOfMonth、endOfMonth方法
- 修复EmpPosOrgRelHelper中查询条件添加ISCURRENTDATA过滤
- 在SWCHelper中新增querySalaryByOrgList方法用于查询薪酬数据
- 修复年度调整列表查询中上年度时间范围计算逻辑
- 在报表查询中添加关闭按钮点击事件处理
- 修复权限查询相关代码中的实体ID和过滤条件
- 修复平均人数计算相关逻辑和数据过滤条件
- 添加任期激励金额和单项工资汇总计算功能
wyc преди 1 седмица
родител
ревизия
bcd6599d5a

+ 2 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java

@@ -305,6 +305,8 @@ public class FormConstant {
     public static final String STARTDATE = "startdate";
     /** 结束时间 */
     public static final String ENDDATE = "enddate";
+    /** 用工关系类型 */
+    public static final String LABORRELTYPE = "laborreltype";
     /** 本次加入集团日期*/
     public static final String JOINCOMDATE_KEY = "joincomdate";
     /** 首次加入集团日期*/

+ 32 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/utils/DateUtil.java

@@ -180,6 +180,17 @@ public class DateUtil {
         return dateTime.plusMonths(months);
     }
 
+    /**
+     * 加月
+     *
+     * @param date 原始日期时间
+     * @param months   要加的月数(可为负数)
+     * @return 计算后的日期时间
+     */
+    public static Date addMonths(Date date, int months) {
+        return toDate(addMonths(toLocalDateTime(date), months));
+    }
+
     /**
      * 减月
      *
@@ -430,6 +441,16 @@ public class DateUtil {
         return dateTime.toLocalDate().atStartOfDay();
     }
 
+    /**
+     * 获取月份的开始时间
+     *
+     * @param date 日期时间
+     * @return 当月第一天 00:00:00
+     */
+    public static Date beginOfMonth(Date date) {
+        return toDate(beginOfMonth(toLocalDateTime(date)));
+    }
+
     /**
      * 获取月份的开始时间
      *
@@ -503,6 +524,17 @@ public class DateUtil {
         return dateTime.with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().atTime(LocalTime.MAX);
     }
 
+
+    /**
+     * 获取月份结束时间
+     *
+     * @param date 日期时间
+     * @return 当月最后一天 23:59:59.999999999
+     */
+    public static Date endOfMonth(Date dateTime) {
+        return toDate(endOfMonth(toLocalDateTime(dateTime)));
+    }
+
     /**
      * 获取季度结束时间
      *

+ 2 - 1
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/hrpi/helper/EmpPosOrgRelHelper.java

@@ -170,7 +170,8 @@ public class EmpPosOrgRelHelper {
                 .and(FormConstant.IS_DELETED, QCP.equals, EnableEnum.NO.getCode())
                 .and(FormConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
                 .and(FormConstant.STARTDATE, QCP.less_equals, new Date())
-                .and(FormConstant.ENDDATE, QCP.large_equals, new Date());
+                .and(FormConstant.ENDDATE, QCP.large_equals, new Date())
+                .and(FormConstant.ISCURRENTDATA, QCP.equals, EnableEnum.YES.getCode());
 
         // 添加额外查询条件(如果有)
         if (otherFilter != null) {

+ 39 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/swc/helper/SWCHelper.java

@@ -142,6 +142,45 @@ public class SWCHelper {
         return calTableDyns;
     }
 
+    /**
+     * 按薪资业务单元 和 薪酬项目查询薪酬数据
+     * @param orgIds
+     * @param startdate
+     * @param enddate
+     * @return
+     */
+    public static DynamicObjectCollection querySalaryByOrgList(List<Long> orgIds,List<String> itemNumber, Date startdate, Date enddate, String type) {
+
+        // 获取核算列表信息
+        QFilter filter = new QFilter("org.id", QCP.in, orgIds);
+        if(type.equals("10")){
+            filter.and("caltask.paydate", QCP.large_equals, startdate);
+            filter.and("caltask.paydate", QCP.less_equals, enddate);
+        }else{
+            filter.and("caltask.payrolldate", QCP.large_equals, startdate);
+            filter.and("caltask.payrolldate", QCP.less_equals, enddate);
+        }
+        if(itemNumber != null && !itemNumber.isEmpty()){
+            filter.and("hsas_caltableentry.salaryitem.number", QCP.in, itemNumber);
+        }
+        //filter.and("caltask.taskstatuse", QCP.equals, "4");   ///任务状态  已审核 7  审批通过 4
+        filter.and("hsas_caltableentry.calamountvalue", QCP.large_than, 0);
+        String orderStr = "hsas_caltableentry.salaryitem.statisticstag.number";
+        String selectFields = "calpersonid,caltask.id,caltask.org.name,caltask.calrule.name,caltask.calcount,hsas_caltableentry.salaryitem.number,hsas_caltableentry.salaryitem.name,hsas_caltableentry.calamountvalue,hsas_caltableentry.salaryitem.statisticstag.number,org.id";
+        if(type.equals("10")){
+            selectFields = selectFields + ",caltask.paydate as bizdate";
+            //orderStr = "caltask.paydate";
+        }else{
+            selectFields = selectFields + ",caltask.payrolldate as bizdate";
+            //orderStr = "caltask.payrolldate";
+        }
+        selectFields = selectFields + ",caltask.paydate,caltask.payrolldate";
+
+        DynamicObjectCollection calTableDyns = QueryServiceHelper.query(FormConstant.HSAS_CALTABLE, selectFields, new QFilter[]{filter}, orderStr);
+
+        return calTableDyns;
+    }
+
     /**
      * 根据用户ID查询员工ID
      * @param userId

+ 13 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/report/KeyBeHavEvalReptQueryFromPlugin.java

@@ -6,6 +6,7 @@ import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.ShowType;
 import kd.bos.form.control.Control;
+import kd.bos.form.control.events.BeforeItemClickEvent;
 import kd.bos.form.control.events.RowClickEvent;
 import kd.bos.form.control.events.RowClickEventListener;
 import kd.bos.form.events.AfterDoOperationEventArgs;
@@ -75,6 +76,18 @@ public class KeyBeHavEvalReptQueryFromPlugin extends AbstractFormPlugin implemen
                 }
             }
         });
+        this.addItemClickListeners(FormConstant.TOOLBARAP);
+        this.addItemClickListeners(new String[]{"btnclose"});
+    }
+
+    public void beforeItemClick(BeforeItemClickEvent evt) {
+        super.beforeItemClick(evt);
+        String itemKey = evt.getItemKey();
+        if ("nckd_tblclose".equals(itemKey)) {
+            this.getView().getParentView().invokeOperation("close");
+            this.getView().sendFormAction(this.getView().getParentView());
+        }
+
     }
 
     @Override

+ 17 - 5
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/report/KeyBeHavEvalReptQueryPlugin.java

@@ -9,6 +9,8 @@ import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.entity.cache.AppCache;
+import kd.bos.entity.cache.IAppCache;
 import kd.bos.entity.report.AbstractReportColumn;
 import kd.bos.entity.report.AbstractReportListDataPlugin;
 import kd.bos.entity.report.DynamicReportColumnEvent;
@@ -17,7 +19,10 @@ import kd.bos.entity.report.ReportColumn;
 import kd.bos.entity.report.ReportQueryParam;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
+import kd.bos.permission.api.HasPermOrgResult;
 import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.parameter.SystemParamServiceHelper;
+import kd.bos.servicehelper.permission.PermissionServiceHelper;
 import kd.hr.hbp.common.model.AuthorizedOrgResultWithSub;
 import kd.hr.hbp.common.model.OrgSubInfo;
 import kd.sdk.hr.hbp.business.helper.permission.HRPermissionServiceHelper;
@@ -64,6 +69,7 @@ public class KeyBeHavEvalReptQueryPlugin extends AbstractReportListDataPlugin im
      */
     @Override
     public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
+
         // 1. 获取权限范围内的组织ID
         List<Long> authorizedOrgIds = getAuthorizedOrgIds();
         
@@ -79,9 +85,14 @@ public class KeyBeHavEvalReptQueryPlugin extends AbstractReportListDataPlugin im
         // 5. 查询主表数据
         // 处理快速过滤条件
         QFilter qFilter = QFilter.of("1=1");
+        if (authorizedOrgIds != null && !authorizedOrgIds.isEmpty()) {
+            qFilter.and(String.join(".", FormConstant.NCKD_PERSON, FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG), QCP.in, authorizedOrgIds);
+        }
+
         processFastFilter(reportQueryParam, qFilter);
         //其他过滤条件
         processFilter(reportQueryParam, qFilter);
+
         DataSet mainTableDataSet = queryMainTableDataSet(qFilter);
         
         // 6. 关联主表和行转列结果
@@ -172,9 +183,9 @@ public class KeyBeHavEvalReptQueryPlugin extends AbstractReportListDataPlugin im
     private List<Long> getAuthorizedOrgIds() {
         Long currentUserId = RequestContext.get().getCurrUserId();
         AuthorizedOrgResultWithSub userAdminOrgWithSub = HRPermissionServiceHelper.getUserAdminOrgsWithSub(
-                currentUserId, "nckd_psms", "nckd_keybehavconf",
+                currentUserId, "nckd_psmsbase", "nckd_keybehavconf",
                 PermItemConst.ITEM_VIEW, "nckd_org", new HashMap<>());
-        
+
         if (userAdminOrgWithSub.isHasAllOrgPerm()) {
             return new ArrayList<>(); // 如果有所有组织权限,返回空列表表示无限制
         }
@@ -188,8 +199,7 @@ public class KeyBeHavEvalReptQueryPlugin extends AbstractReportListDataPlugin im
     private DataSet queryKeyBeHavEvalProjRsltDataSet(List<Long> orgIds) {
         QueryFieldBuilder resultFieldBuilder = createResultFieldBuilder();
         QFilter filter = createOrgFilter(orgIds);
-        
-        return QueryServiceHelper.queryDataSet("", 
+        return QueryServiceHelper.queryDataSet(this.getClass().getName(),
                 PositionStructureConstant.KEYBEHAVEVALPROJRSLT_ENTITYID, 
                 resultFieldBuilder.buildSelect(), 
                 new QFilter[]{filter}, 
@@ -213,7 +223,9 @@ public class KeyBeHavEvalReptQueryPlugin extends AbstractReportListDataPlugin im
     private QFilter createOrgFilter(List<Long> orgIds) {
         QFilter filter = QFilter.of("1=1");
         if (orgIds != null && !orgIds.isEmpty()) {
-            filter.and(String.join(".", FormConstant.NCKD_ORG, FormConstant.ID_KEY), QCP.in, orgIds);
+            filter.and(String.join(".",PositionStructureConstant.NCKD_KEYBEHAVCONFENTRY,"nckd_keybehavconf",FormConstant.NCKD_ORG, FormConstant.ID_KEY), QCP.in, orgIds);
+            filter.and(String.join(".",FormConstant.NCKD_PERSON,FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG), QCP.in, orgIds);
+
         }
         return filter;
     }

+ 14 - 2
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/result/AnnualPerfDetailReportListDataPlugin.java

@@ -2,6 +2,7 @@ package nckd.jxccl.opmc.pm.plugin.form.result;
 
 import kd.bos.algo.DataSet;
 import kd.bos.algo.GroupbyDataSet;
+import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.LocaleString;
 import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.QueryEntityType;
@@ -12,7 +13,9 @@ import kd.bos.entity.report.ReportColumn;
 import kd.bos.entity.report.ReportQueryParam;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.model.PermissionStatus;
 import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
+import kd.sdk.hr.hbp.business.helper.permission.HRPermissionServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.algo.DistinctConcatFunction;
 import nckd.jxccl.base.common.constant.FormConstant;
@@ -22,6 +25,7 @@ import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;
 
 import java.time.LocalDate;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -46,7 +50,7 @@ public class AnnualPerfDetailReportListDataPlugin extends AbstractReportListData
         int fiveYearsAgo = LocalDate.now().minusYears(now.getYear() - 2018).getYear();
         Date beginDate = DateUtil.toDate(LocalDate.of(fiveYearsAgo, 1, 1));
 
-        int currentYear = LocalDate.now().getYear() - 1; // 不包含今年
+        int currentYear = LocalDate.now().getYear(); // 不包含今年
         Date endDate = DateUtil.toDate(LocalDate.of(currentYear, 1, 1));
         //查询最近5年的数据
         /*QFilter qFilter = new QFilter(PerfManagerFormConstant.NCKD_BEGINYEAR, QCP.less_equals, endDate)
@@ -60,6 +64,14 @@ public class AnnualPerfDetailReportListDataPlugin extends AbstractReportListData
         //其他过滤条件
         processFilter(reportQueryParam, qFilter);
 
+        //权限过滤
+        QFilter dataRule = HRPermissionServiceHelper.getDataRule(
+                RequestContext.get().getCurrUserId(), "nckd_pm", PerfManagerFormConstant.PERFMANAGER_ENTITYID,
+                PermissionStatus.View, new HashMap<>());
+        if(dataRule != null){
+            qFilter.and(dataRule);
+        }
+
         // 执行基础查询
         QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType("annualperfdetailquery");
         DataSet dataSet = HRQueryEntityHelper.getInstance().getQueryDataSet(queryEntityType,queryFieldBuilder.buildSelect(), new QFilter[]{qFilter}, null);
@@ -128,7 +140,7 @@ public class AnnualPerfDetailReportListDataPlugin extends AbstractReportListData
     public List<AbstractReportColumn> getColumns(List<AbstractReportColumn> columns) throws Throwable {
         LocalDate now = LocalDate.now();
         int fiveYearsAgo = LocalDate.now().minusYears(now.getYear()-2018).getYear();
-        int currentYear = LocalDate.now().getYear() - 1; // 不包含今年
+        int currentYear = LocalDate.now().getYear() ; // 不包含今年
 
         for (AbstractReportColumn column : columns) {
             if (column instanceof ReportColumn) {

+ 1 - 2
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/empmgt/SubCoHeadServiceListPlugin.java

@@ -159,7 +159,6 @@ public class SubCoHeadServiceListPlugin extends AbstractListPlugin implements Pl
                 .add(MasConstant.NCKD_CHANGETIME)
                 .add(MasConstant.NCKD_POSNAME)
                 .addIdNumberName(MasConstant.NCKD_POSCHTP)
-                .addIdNumberName(MasConstant.NCKD_POSLEVEL)
                 .addIdNumberName(MasConstant.NCKD_POSGRADE)
                 .addIdNumberName(MasConstant.NCKD_APPRWAY)
                 .add(MasConstant.NCKD_OFFICEDEPT)
@@ -168,7 +167,7 @@ public class SubCoHeadServiceListPlugin extends AbstractListPlugin implements Pl
                 .addIdNumberName(MasConstant.NCKD_ORGPOSGRD)
                 .addIdNumberName(MasConstant.EMPLOYEE_KEY)
                 .orderDesc(MasConstant.STARTDATE, MasConstant.ENDDATE);
-        QFilter allPartyPoshFilter = new QFilter(MasConstant.EMPLOYEE_KEY, QCP.not_in, employeeIds);
+        QFilter allPartyPoshFilter = new QFilter(String.join(".",MasConstant.EMPLOYEE_KEY,FormConstant.ID_KEY), QCP.not_in, employeeIds);
         if(!payUnitIdList.isEmpty()){
             allPartyPoshFilter.and(String.join(".",MasConstant.NCKD_PAYUNIT,FormConstant.ID_KEY), QCP.in, payUnitIdList);
         }

+ 0 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/mas/plugin/form/empmgt/TenurePersonListListPlugin.java

@@ -121,7 +121,6 @@ public class TenurePersonListListPlugin extends AbstractListPlugin implements Pl
                 .add(MasConstant.NCKD_CHANGETIME)
                 .add(MasConstant.NCKD_POSNAME)
                 .addIdNumberName(MasConstant.NCKD_POSCHTP)
-                .addIdNumberName(MasConstant.NCKD_POSLEVEL)
                 .addIdNumberName(MasConstant.NCKD_POSGRADE)
                 .addIdNumberName(MasConstant.NCKD_APPRWAY)
                 .add(MasConstant.NCKD_OFFICEDEPT)

+ 169 - 15
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/stm/plugin/form/appr/GrpSalStlApprFormPlugin.java

@@ -1,17 +1,24 @@
 package nckd.jxccl.swc.stm.plugin.form.appr;
 
+import com.google.common.collect.Lists;
 import kd.bos.algo.Algo;
 import kd.bos.algo.AlgoContext;
 import kd.bos.algo.DataSet;
 import kd.bos.algo.Row;
+import kd.bos.common.enums.EnableEnum;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.QueryEntityType;
 import kd.bos.form.control.events.ItemClickEvent;
 import kd.bos.form.control.events.ItemClickListener;
 import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.QueryServiceHelper;
+import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
@@ -40,6 +47,7 @@ import java.util.stream.Collectors;
 */
 public class GrpSalStlApprFormPlugin extends AbstractFormPlugin implements Plugin, ItemClickListener {
 
+    private static final Log logger = LogFactory.getLog(GrpSalStlApprFormPlugin.class);
     @Override
     public void registerListener(EventObject e) {
         //监听工具栏
@@ -80,11 +88,13 @@ public class GrpSalStlApprFormPlugin extends AbstractFormPlugin implements Plugi
                 //获取上年度数据
                 Map<Long, List<DynamicObject>> lastYearDataMap = getLastYearData(year, unitIds);
                 //计算中高层不同类别人员的平均人数和薪酬总额
-                Map<Long, Result> longResultMap = avgPeopleNum(year, unitIds);
+                Map<Long, Result> avgMasPeopleNumMap = avgMasPeopleNum(year, unitIds);
                 //按单位汇总任期激励金额
-                Map<Long, BigDecimal> longBigDecimalMap = sumTermBonusByUnit(year, unitIds);
+                Map<Long, BigDecimal> sumTermBonusByUnit = sumTermBonusByUnit(year, unitIds);
                 //集团核定单项”+“优秀生津贴”项目薪酬数据
-
+                Map<Long, BigDecimal> sumItemMap = sumItem(year, unitIds);
+                //
+                Map<Long, BigDecimal> avgPeopleNumMap = avgPeopleNum(year, unitIds);
                 for (DynamicObject entry : entryEntity) {
                     long unitId = entry.getLong(String.join(".", StmConstant.NCKD_UNIT, StmConstant.ID_KEY));
                     if(unitId > 0){
@@ -104,21 +114,29 @@ public class GrpSalStlApprFormPlugin extends AbstractFormPlugin implements Plugi
                             //上年单项工资差额
                             entry.set(StmConstant.NCKD_LYRITEMWGDIFF, lastYearData.getBigDecimal(String.join(".",StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_LYRITEMWGDIFF)));
                         }
-                        Result result = longResultMap.get(unitId);
-                        if(result != null) {
+                        Result avgMasPeopleNum = avgMasPeopleNumMap.get(unitId);
+                        if(avgMasPeopleNum != null) {
                             //负责人累计平均人数
-                            entry.set(StmConstant.NCKD_RESPAVGNUM, result.respAvgNum);
+                            entry.set(StmConstant.NCKD_RESPAVGNUM, avgMasPeopleNum.respAvgNum);
                             //负责人薪酬合计
-                            entry.set(StmConstant.NCKD_RESPWGTTL, result.resPwgTtl);
+                            entry.set(StmConstant.NCKD_RESPWGTTL, avgMasPeopleNum.resPwgTtl);
                             //专务、巡察专员累计平均人数
-                            entry.set(StmConstant.NCKD_SPECINSPAVGNUM, result.specInspAvgNum);
+                            entry.set(StmConstant.NCKD_SPECINSPAVGNUM, avgMasPeopleNum.specInspAvgNum);
                             //专务、巡察专员薪酬合计
-                            entry.set(StmConstant.NCKD_SPECINSPWGTTL, result.specInspWgTtl);
+                            entry.set(StmConstant.NCKD_SPECINSPWGTTL, avgMasPeopleNum.specInspWgTtl);
                         }
-                        BigDecimal sumTermBonus = longBigDecimalMap.get(unitId);
+                        BigDecimal sumTermBonus = sumTermBonusByUnit.get(unitId);
                         if(sumTermBonus != null){
                             entry.set(StmConstant.NCKD_TERMBONUS, sumTermBonus);
                         }
+
+                        BigDecimal sumItem = sumItemMap.get(unitId);
+                        if(sumItem != null){
+                            entry.set(StmConstant.NCKD_ONETIMEITEMWG, sumItem);
+                        }
+                        BigDecimal avgPeopleNum = avgPeopleNumMap.get(unitId);
+                        entry.set(StmConstant.NCKD_ALLEMPAVGNUM, avgPeopleNum);
+
                     }
                 }
                 this.getView().updateView(StmConstant.NCKD_ENTRYENTITY);
@@ -128,6 +146,123 @@ public class GrpSalStlApprFormPlugin extends AbstractFormPlugin implements Plugi
         }
     }
 
+    /**
+     * 统计平均人数
+     * ((起始月月初数据+起始月月末数据)/2+……(结束月月初数据+结束月月末数据)/2)/总月数
+     * @param year 年份
+     * @param unitIds 单位
+     * @return: void
+     * @author W.Y.C
+     * @date: 2025/12/31 14:43
+     */
+    private Map<Long,BigDecimal> avgPeopleNum(Date year, List<Long> unitIds){
+        try(AlgoContext context = Algo.newContext()) {
+            //计算方式为:((起始月月初数据+起始月月末数据)/2+……(结束月月初数据+结束月月末数据)/2)/总月数
+            Date beginDate = DateUtil.beginOfYear(year);
+            Date endDate = DateUtil.endOfDay(year);
+            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                    .addIdNumberNameWithExtras(new String[]{StmConstant.NCKD_EMPLOYEE}, FormConstant.EMP_NUMBER_KEY)
+                    .add(FormConstant.STARTDATE)
+                    .add(FormConstant.ENDDATE)
+                    .addIdNumberName(FormConstant.COMPANY_KEY)
+                    .add(FormConstant.HRPI_EMPENTREL, FormConstant.STARTDATE)
+                    .add(FormConstant.HRPI_EMPENTREL, FormConstant.ENDDATE)
+                    .addIdNumberName(FormConstant.HRPI_EMPENTREL, FormConstant.LABORRELTYPE)
+                    .addIdNumberName(FormConstant.HRPI_EMPENTREL, FormConstant.LABOR_REL_STATUS)
+                    .add(FormConstant.HRPI_EMPENTREL, FormConstant.IS_HIRED);
+            QFilter queryFilter = new QFilter(FormConstant.COMPANY_KEY, QCP.in, unitIds)
+                    .and(FormConstant.IS_SEQLATESTRECORD, QCP.equals, EnableEnum.YES.getCode())
+                    .and(FormConstant.IS_DELETED, QCP.equals, EnableEnum.NO.getCode())
+                    .and(FormConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
+                    .and(FormConstant.ISCURRENTDATA, QCP.equals, EnableEnum.YES.getCode())
+                    //取当年还有效的人员
+                    .and(FormConstant.ENDDATE, QCP.large_equals, beginDate)
+                    .and(String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.ENDDATE), QCP.large_equals, beginDate);
+            QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType("personfilequery");
+            DataSet dataSet = HRQueryEntityHelper.getInstance().getQueryDataSet(queryEntityType, queryFieldBuilder.buildSelect(), new QFilter[]{queryFilter}, null);
+
+            // 计算所有职工平均人数
+            // 用工关系类型:雇佣类(1010_S,1090_S)、劳务类(JT_1040)、返聘类(JT_1050)、外部类(1030_S)
+            // 用工状态:在职(ishired=true)
+            // 获取当前日期以确定需要计算的月份范围
+            Date currentDate = new Date();
+            Date currentYearBegin = DateUtil.beginOfYear(currentDate);
+            int totalMonths;
+            if (DateUtil.getYear(year) == DateUtil.getYear(currentDate)) {
+                // 如果是当年,只计算到当前月份
+                totalMonths = DateUtil.getMonthValue(currentDate);
+            } else {
+                // 如果不是当年,计算12个月
+                totalMonths = 12;
+            }
+
+            Map<Integer,Map<Long, AvgPeopleNumResult>> monthAvgCountMap = new HashMap<>();
+            for (int month = 1; month <= totalMonths; month++) {
+                Date monthBeginDate = DateUtil.beginOfMonth(DateUtil.addMonths(beginDate, month - 1));
+                String monthBeginDateStr = DateUtil.format(monthBeginDate, DateUtil.NORM_DATE_PATTERN);
+                Date monthEndDate = DateUtil.endOfMonth(DateUtil.addMonths(beginDate, month - 1));
+                String monthEndDateStr = DateUtil.format(monthEndDate, DateUtil.NORM_DATE_PATTERN);
+
+                // 获取月初人数:在月初仍然在职的人员数量
+                String monthBeginFilter = String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.IS_HIRED) + "=true " +
+                        "and " + String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.LABORRELTYPE,FormConstant.NUMBER_KEY) + " in('1010_S','1090_S','1030_S','JT_1050','JT_1040') " +
+                        "and " + String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.STARTDATE) + " <= to_date('" + monthBeginDateStr + "','yyyy-MM-dd') " +
+                        "and (" + String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.ENDDATE) + " is null or " +
+                        String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.ENDDATE) + " >= to_date('" + monthBeginDateStr + "','yyyy-MM-dd'))";
+
+                Map<Long, AvgPeopleNumResult> resultMap = new HashMap<>();
+                DataSet beginMonthDataSet = dataSet.copy().filter(monthBeginFilter).groupBy(new String[]{String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY),String.join(".", FormConstant.COMPANY_KEY, FormConstant.NAME_KEY)}).count().finish();
+                while (beginMonthDataSet.hasNext()) {
+                    Row row = beginMonthDataSet.next();
+                    Long companyId = row.getLong(String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY));
+                    String companyName = row.getString(String.join(".", FormConstant.COMPANY_KEY, FormConstant.NAME_KEY));
+                    Integer count = row.getInteger("count");
+                    resultMap.computeIfAbsent(companyId, k -> new AvgPeopleNumResult()).beginCount = count;
+                    logger.info("【{}】截至【{}】在职人数:{}",companyName,monthBeginDateStr,count);
+                }
+                // 获取月末人数:在月末仍然在职的人员数量
+                String monthEndFilter = String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.IS_HIRED) + "=true " +
+                        "and " + String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.LABORRELTYPE,FormConstant.NUMBER_KEY) + " in('1010_S','1090_S','1030_S','JT_1050','JT_1040') " +
+                        "and " + String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.STARTDATE) + " <= to_date('" + monthEndDateStr + "','yyyy-MM-dd') " +
+                        "and (" + String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.ENDDATE) + " is null or " +
+                        String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.ENDDATE) + " >= to_date('" + monthEndDateStr + "','yyyy-MM-dd'))";
+
+                DataSet endMonthDataSet = dataSet.copy().filter(monthEndFilter).groupBy(new String[]{String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY),String.join(".", FormConstant.COMPANY_KEY, FormConstant.NAME_KEY)}).count().finish();
+                while (endMonthDataSet.hasNext()) {
+                    Row row = endMonthDataSet.next();
+                    Long companyId = row.getLong(String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY));
+                    String companyName = row.getString(String.join(".", FormConstant.COMPANY_KEY, FormConstant.NAME_KEY));
+                    Integer count = row.getInteger("count");
+                    resultMap.computeIfAbsent(companyId, k -> new AvgPeopleNumResult()).endCount = count;
+                    logger.info("【{}】截至【{}】在职人数:{}",companyName,monthEndDateStr,count);
+                }
+                monthAvgCountMap.put(month, resultMap);
+            }
+
+            Map<Long, BigDecimal> unitAvgMap = new HashMap<>();
+            for (Long unitId : unitIds) {
+                BigDecimal unitTotalAvgCount = BigDecimal.ZERO;
+                for (int month = 1; month <= totalMonths; month++) {
+                    Map<Long, AvgPeopleNumResult> resultMap = monthAvgCountMap.get(month);
+                    AvgPeopleNumResult avgPeopleNumResult = resultMap.get(unitId);
+                    if(avgPeopleNumResult != null) {
+                        //计算月平均人数:(月初人数 + 月末人数) / 2
+                        BigDecimal monthAvgCount = new BigDecimal(avgPeopleNumResult.beginCount + avgPeopleNumResult.endCount).divide(new BigDecimal(2), 2, RoundingMode.HALF_UP);
+                        unitTotalAvgCount = unitTotalAvgCount.add(monthAvgCount);
+                    }
+                }
+                // 计算全年平均人数:总平均人数 / 总月份数
+                BigDecimal totalAvgCount = unitTotalAvgCount.divide(new BigDecimal(totalMonths), 2, RoundingMode.HALF_UP);
+                unitAvgMap.put(unitId, totalAvgCount);
+            }
+            return unitAvgMap;
+        }
+    }
+
+    class AvgPeopleNumResult {
+        int beginCount;
+        int endCount;
+    }
     /**
      * 获取上年度数据
      * @param year 年份
@@ -165,7 +300,7 @@ public class GrpSalStlApprFormPlugin extends AbstractFormPlugin implements Plugi
      * @param unitIds 单位ID列表
      * @return 每个单位的计算结果映射
      */
-    private Map<Long,Result> avgPeopleNum(Date year, List<Long> unitIds){
+    private Map<Long,Result> avgMasPeopleNum(Date year, List<Long> unitIds){
         Map<Long,Result> result = new HashMap<>();
         
         // 定义常量
@@ -338,14 +473,33 @@ public class GrpSalStlApprFormPlugin extends AbstractFormPlugin implements Plugi
         }
     }
     /**
-     * 按单位汇总任期激励金额
+     * 按单位汇总集团核定单项工资小计、优秀生津贴
      * @param year 年份
      * @param unitIds 单位ID列表
      * @return 每个单位的任期激励总额映射
      */
-    /*private Map<Long, BigDecimal> sumTermBonusByUnit1(Date year, List<Long> unitIds){
-        SWCHelper.querySalaryList(unitPersonMap.keySet(), beginDate, endDate, "-1")
-    }*/
+    private Map<Long, BigDecimal> sumItem(Date year, List<Long> unitIds){
+        Date beginDate = DateUtil.beginOfYear(year);
+        Date endDate = DateUtil.endOfDay(year);
+        //集团核定单项工资小计、优秀生津贴
+        List<String> itemNumbers = Lists.newArrayList("JT391","JT050");
+        DynamicObjectCollection query = SWCHelper.querySalaryByOrgList(unitIds, itemNumbers, beginDate, endDate, "-1");
+
+        if(!query.isEmpty()){
+            // 按单位分组并汇总金额
+            return query.stream()
+                    .collect(Collectors.groupingBy(
+                            obj -> obj.getLong(String.join(".", FormConstant.ORG_KEY, MasConstant.ID_KEY)),
+                            Collectors.reducing(
+                                    BigDecimal.ZERO,
+                                    obj -> obj.getBigDecimal("hsas_caltableentry.calamountvalue"),
+                                    BigDecimal::add
+                            )
+                    ));
+        }else{
+            return new HashMap<>();
+        }
+    }
 
     class Result {
         /** 负责人累计平均人数 */