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;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.swc.helper.SWCHelper;
import nckd.jxccl.swc.constants.MasConstant;
import nckd.jxccl.swc.constants.StmConstant;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* 集团工资结算核定
* 实体标识：nckd_grpsalstlappr
* @author W.Y.C
* @date 2025/12/30 19:09
* @version 1.0
*/
public class GrpSalStlApprFormPlugin extends AbstractFormPlugin implements Plugin, ItemClickListener {

    private static final Log logger = LogFactory.getLog(GrpSalStlApprFormPlugin.class);
    @Override
    public void registerListener(EventObject e) {
        //监听工具栏
        this.addItemClickListeners("nckd_advcontoolbarap");
    }

    @Override
    public void itemClick(ItemClickEvent evt) {
        String itemKey = evt.getItemKey();
        if(itemKey.equalsIgnoreCase("nckd_calculate")){
            Date year = ConvertUtil.toDate(this.getModel().getValue(StmConstant.NCKD_YEAR));
            if(year == null){
                this.getView().showTipNotification("请选择年度");
            }else{
                calculate();
            }
        }
    }

    private void calculate(){
        Date year = ConvertUtil.toDate(this.getModel().getValue(StmConstant.NCKD_YEAR));
        DynamicObjectCollection entryEntity = this.getModel().getDataEntity(true).getDynamicObjectCollection(StmConstant.NCKD_ENTRYENTITY);
        if(!entryEntity.isEmpty()){
            List<Long> unitIds = new ArrayList<>();
            for (DynamicObject entry : entryEntity) {
                DynamicObject unit = entry.getDynamicObject(StmConstant.NCKD_UNIT);
                if(unit != null){
                    long unitId = unit.getLong(StmConstant.ID_KEY);
                    if(unitId > 0) {
                        unitIds.add(unitId);
                    }
                }
            }
            if(unitIds.isEmpty()){
                this.getView().showTipNotification("请先选择二级单位！");
            }else{

                //获取上年度数据
                Map<Long, List<DynamicObject>> lastYearDataMap = getLastYearData(year, unitIds);
                //计算中高层不同类别人员的平均人数和薪酬总额
                Map<Long, Result> avgMasPeopleNumMap = avgMasPeopleNum(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){
                        List<DynamicObject> lastYearDataList = lastYearDataMap.get(unitId);
                        if(lastYearDataList != null && !lastYearDataList.isEmpty()){
                            DynamicObject lastYearData = lastYearDataList.get(0);
                            //上年实际计提工资总额与应提工资总额差额
                            if(lastYearData.containsProperty(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYACTVSEXPDIFF))) {
                                entry.set(StmConstant.NCKD_LYRACTVSEXPDIFF, lastYearData.getBigDecimal(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYACTVSEXPDIFF)));
                            }
                            //上年补提或冲回以前年度差额
                            if(lastYearData.containsProperty(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYPRIORADJDIFF2))) {
                                entry.set(StmConstant.NCKD_LYRPRIORADJDIFF, lastYearData.getBigDecimal(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYPRIORADJDIFF2)));
                            }
                            //上年年薪人员差额
                            if(lastYearData.containsProperty(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYANNSALDIFF))) {
                                entry.set(StmConstant.NCKD_LYRANNSALDIFF, lastYearData.getBigDecimal(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYANNSALDIFF)));
                            }
                            //上年任期激励差额
                            if(lastYearData.containsProperty(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYTERMBONUSDIFF))) {
                                entry.set(StmConstant.NCKD_LYRTERMBONUSDIFF, lastYearData.getBigDecimal(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYTERMBONUSDIFF)));
                            }
                            //上年组织绩效差额
                            if(lastYearData.containsProperty(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYORGPERFDIFF))) {
                                entry.set(StmConstant.NCKD_LYRORGPERFDIFF, lastYearData.getBigDecimal(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYORGPERFDIFF)));
                            }
                            //上年单项工资差额
                            if(lastYearData.containsProperty(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYITEMWGDIFF))) {
                                entry.set(StmConstant.NCKD_LYRITEMWGDIFF, lastYearData.getBigDecimal(String.join(".", StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_CYITEMWGDIFF)));
                            }

                        }
                        Result avgMasPeopleNum = avgMasPeopleNumMap.get(unitId);
                        if(avgMasPeopleNum != null) {
                            //负责人累计平均人数
                            entry.set(StmConstant.NCKD_RESPAVGNUM, avgMasPeopleNum.respAvgNum);
                            //负责人薪酬合计
                            entry.set(StmConstant.NCKD_RESPWGTTL, avgMasPeopleNum.resPwgTtl);
                            //专务、巡察专员累计平均人数
                            entry.set(StmConstant.NCKD_SPECINSPAVGNUM, avgMasPeopleNum.specInspAvgNum);
                            //专务、巡察专员薪酬合计
                            entry.set(StmConstant.NCKD_SPECINSPWGTTL, avgMasPeopleNum.specInspWgTtl);
                        }
                        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);
            }
        }else{
            this.getView().showTipNotification("请先添加数据！");
        }
    }

    /**
     * 统计平均人数
     * （（起始月月初数据+起始月月末数据）/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 年份
     * @param unitIds 单位ID列表
     * @return 每个单位的上年度数据映射
     */
    private Map<Long,List<DynamicObject>> getLastYearData(Date year, List<Long> unitIds){
        Date lastYear = DateUtil.minusYears(year, 1);
        Date beginDate = DateUtil.beginOfYear(lastYear);
        Date endDate = DateUtil.endOfYear(lastYear);
        QFilter qFilter = new QFilter(StmConstant.NCKD_YEAR, QCP.large_equals,beginDate)
                .and(StmConstant.NCKD_YEAR, QCP.less_equals, endDate)
                .and(String.join(".",StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_UNIT), QCP.in, unitIds);
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .addIdNumberName(StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_UNIT)
                .add(StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_CYACTVSEXPDIFF)
                .add(StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_CYPRIORADJDIFF2)
                .add(StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_CYANNSALDIFF)
                .add(StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_CYTERMBONUSDIFF)
                .add(StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_CYORGPERFDIFF)
                .add(StmConstant.NCKD_ENTRYENTITY,StmConstant.NCKD_CYITEMWGDIFF);
        DynamicObjectCollection query = QueryServiceHelper.query(StmConstant.GRPSALSTLAPPR_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
        return query.stream()
                .collect(Collectors.groupingBy(
                        obj -> obj.getLong(String.join(".",StmConstant.NCKD_ENTRYENTITY, StmConstant.NCKD_UNIT,FormConstant.ID_KEY))
                ));
    }



    /**
     * 计算不同职位类别的平均人数和薪酬总额
     * 
     * @param year 年份
     * @param unitIds 单位ID列表
     * @return 每个单位的计算结果映射
     */
    private Map<Long,Result> avgMasPeopleNum(Date year, List<Long> unitIds){
        Map<Long,Result> result = new HashMap<>();
        // 定义常量
        final String SALARY_ITEM_NUMBER = "JT_477"; // 实发工资
        final BigDecimal MONTHS_IN_YEAR = new BigDecimal(12); // 一年的月份数
        final int DECIMAL_SCALE = 2; // 保留小数位数
        
        try(AlgoContext context = Algo.newContext()) {
            Date beginDate = DateUtil.beginOfYear(year);
            Date endDate = DateUtil.endOfDay(year);
            QFilter qFilter = new QFilter(StmConstant.NCKD_YEAR, QCP.large_equals, beginDate)
                    .and(StmConstant.NCKD_YEAR, QCP.less_equals, endDate)
                    .and(StmConstant.NCKD_PAYUNIT, QCP.in, unitIds);
            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                    .addIdNumberName(StmConstant.NCKD_PAYUNIT)
                    .addIdNumberNameWithExtras(new String[]{StmConstant.NCKD_EMPLOYEE}, FormConstant.EMP_NUMBER_KEY)
                    .add(MasConstant.NCKD_ISDIRCADRE)
                    .add(MasConstant.NCKD_POSNAME)
                    .add(MasConstant.NCKD_SERVICEMONTHS);
            DataSet dataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), MasConstant.SUBCOHEADSERVICE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter}, null,1000000);

            // 计算负责人类别（不包含专务和巡察专员的直管干部）
            calculateCategoryResult(dataSet.copy(), result,
                MasConstant.NCKD_POSNAME + " not like '%专务%' and " + MasConstant.NCKD_POSNAME + " not like '%巡察专员%' and " + MasConstant.NCKD_ISDIRCADRE + "=true",
                Result::setRespAvgNum, Result::setResPwgTtl, beginDate, endDate);

            // 计算专务和巡察专员类别
            calculateCategoryResult(dataSet.copy(), result,
                "("+MasConstant.NCKD_POSNAME + " like '%专务%' or " + MasConstant.NCKD_POSNAME + " like '%巡察专员%')",
                Result::setSpecInspAvgNum, Result::setSpecInspWgTtl, beginDate, endDate);
        }
        return result;
    }


    /**
     * 计算特定类别的结果
     * 
     * @param dataSet 原始数据集
     * @param result 结果映射
     * @param filter 过滤条件
     * @param avgNumSetter 平均人数设置器
     * @param wgTtlSetter 薪酬总额设置器
     * @param beginDate 查询开始日期
     * @param endDate 查询结束日期
     */
    private void calculateCategoryResult(DataSet dataSet, Map<Long, Result> result, String filter,
                                         java.util.function.BiConsumer<Result, BigDecimal> avgNumSetter,
                                         java.util.function.BiConsumer<Result, BigDecimal> wgTtlSetter,
                                         Date beginDate, Date endDate) {
        // 定义常量
        final String SALARY_ITEM_NUMBER = "JT_477"; // 实发工资
        final BigDecimal MONTHS_IN_YEAR = new BigDecimal(12); // 一年的月份数
        final int DECIMAL_SCALE = 2; // 保留小数位数
        
        DataSet filteredDataSet = dataSet.filter(filter);
        DataSet calcSumDataSet = filteredDataSet.copy()
                .groupBy(new String[]{String.join(".", StmConstant.NCKD_PAYUNIT, StmConstant.ID_KEY)})
                .sum(MasConstant.NCKD_SERVICEMONTHS, "sum")
                .finish();
        
        // 计算平均人数
        while (calcSumDataSet.hasNext()) {
            Row next = calcSumDataSet.next();
            Long payUnitId = next.getLong(String.join(".", StmConstant.NCKD_PAYUNIT, StmConstant.ID_KEY));
            BigDecimal sum = next.getBigDecimal("sum");
            BigDecimal avg = calculateAverage(sum, MONTHS_IN_YEAR, DECIMAL_SCALE);
            result.computeIfAbsent(payUnitId, k -> new Result());
            avgNumSetter.accept(result.get(payUnitId), avg);
        }
        
        // 计算薪酬总额
        Map<Long, List<Long>> unitPersonMap = new HashMap<>(); // 按单位分组的人员ID映射
        Map<Long, Long> personToUnitMap = new HashMap<>(); // 人员ID到单位ID的映射
        
        // 重新遍历过滤后的数据集，建立人员与单位的映射关系
        DataSet personDataSet = filteredDataSet.copy();
        while (personDataSet.hasNext()) {
            Row next = personDataSet.next();
            Long personId = next.getLong(String.join(".", StmConstant.NCKD_EMPLOYEE, StmConstant.ID_KEY));
            Long payUnit = next.getLong(String.join(".", StmConstant.NCKD_PAYUNIT, StmConstant.ID_KEY));
            
            // 按单位分组人员ID
            unitPersonMap.computeIfAbsent(payUnit, k -> new ArrayList<>()).add(personId);
            // 建立人员ID到单位ID的映射
            personToUnitMap.put(personId, payUnit);
        }
        
        if (!unitPersonMap.isEmpty()) {
            List<Long> allPersonIds = unitPersonMap.values().stream()
                    .flatMap(List::stream)
                    .collect(Collectors.toList());
            
            // 获取人员薪酬数据（按薪资所属年月）
            DynamicObjectCollection items = SWCHelper.querySalaryList(allPersonIds, beginDate, endDate, "-1");
            
            // 过滤实发工资项目
            List<DynamicObject> filteredItems = items.stream()
                    .filter(item -> SALARY_ITEM_NUMBER.equals(item.getString("hsas_caltableentry.salaryitem.number")))
                    .collect(Collectors.toList());
            
            // 按单位分组计算薪酬总额
            Map<Long, BigDecimal> unitSalaryMap = new HashMap<>();
            for (DynamicObject item : filteredItems) {
                Long personId = item.getLong("calpersonid");
                // 通过映射直接获取单位ID
                Long unitId = personToUnitMap.get(personId);
                if (unitId != null) {
                    BigDecimal amount = item.getBigDecimal("hsas_caltableentry.calamountvalue");
                    unitSalaryMap.merge(unitId, amount, BigDecimal::add);
                }
            }
            
            // 更新结果中的薪酬总额
            for (Map.Entry<Long, BigDecimal> entry : unitSalaryMap.entrySet()) {
                Long payUnitId = entry.getKey();
                result.computeIfAbsent(payUnitId, k -> new Result());
                wgTtlSetter.accept(result.get(payUnitId), entry.getValue());
            }
        }
    }
    
    /**
     * 计算平均值
     * 
     * @param sum 总和
     * @param divisor 除数
     * @param scale 小数位数
     * @return 计算后的平均值
     */
    private BigDecimal calculateAverage(BigDecimal sum, BigDecimal divisor, int scale) {
        if (sum != null && sum.compareTo(BigDecimal.ZERO) > 0) {
            return sum.divide(divisor, scale, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO;
    }

    /**
     * 按单位汇总任期激励金额
     * @param year 年份
     * @param unitIds 单位ID列表
     * @return 每个单位的任期激励总额映射
     */
    private Map<Long, BigDecimal> sumTermBonusByUnit(Date year, List<Long> unitIds){
        int y = DateUtil.getYear(year);
        // 查询任期激励核定表中对应年份的数据
        // 结束年份的任期激励总金额；
        QFilter qFilter = new QFilter(String.join(".", MasConstant.NCKD_TERM, StmConstant.NAME_KEY), QCP.like, "%-"+y)
                .and(MasConstant.NCKD_PAYUNIT, QCP.in, unitIds);

        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .addIdNumberName(MasConstant.NCKD_PAYUNIT)
                .add(String.join(".", FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TOTALBONUSAMT));

        // 使用正确的实体标识
        DynamicObjectCollection query = QueryServiceHelper.query(MasConstant.ENTLDRTERMBONUSAPPR_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
        if(!query.isEmpty()){
            // 按单位分组并汇总任期激励金额
            return query.stream()
                    .collect(Collectors.groupingBy(
                            obj -> obj.getLong(String.join(".",  MasConstant.NCKD_PAYUNIT, FormConstant.ID_KEY)),
                            Collectors.reducing(
                                    BigDecimal.ZERO,
                                    obj -> obj.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, MasConstant.NCKD_TOTALBONUSAMT)),
                                    BigDecimal::add
                            )
                    ));
        }else{
            return new HashMap<>();
        }
    }
    /**
     * 按单位汇总集团核定单项工资小计、优秀生津贴
     * @param year 年份
     * @param unitIds 单位ID列表
     * @return 每个单位的任期激励总额映射
     */
    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 {
        /** 负责人累计平均人数 */
        public  BigDecimal respAvgNum;
        /** 负责人薪酬合计 */
        public  BigDecimal resPwgTtl;
        /** 专务、巡察专员累计平均人数 */
        public  BigDecimal specInspAvgNum;
        /** 专务、巡察专员薪酬合计 */
        public  BigDecimal specInspWgTtl;
        
        public void setRespAvgNum(BigDecimal respAvgNum) {
            this.respAvgNum = respAvgNum;
        }
        
        public void setResPwgTtl(BigDecimal resPwgTtl) {
            this.resPwgTtl = resPwgTtl;
        }
        
        public void setSpecInspAvgNum(BigDecimal specInspAvgNum) {
            this.specInspAvgNum = specInspAvgNum;
        }
        
        public void setSpecInspWgTtl(BigDecimal specInspWgTtl) {
            this.specInspWgTtl = specInspWgTtl;
        }
    }
}