package nckd.jimin.jyyy.fi.plugin.operate.Helper;

import com.alibaba.fastjson.JSON;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDBizException;
import kd.bos.logging.BizLog;
import kd.bos.org.utils.DynamicObjectUtils;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.fi.gl.util.BigDecimalUtil;
import nckd.jimin.jyyy.fi.common.ReimAmountSourceTypeEnum;
import nckd.jimin.jyyy.fi.common.constant.BillTypeConstants;
import nckd.jimin.jyyy.fi.common.constant.JobPositionBakBillConstant;
import nckd.jimin.jyyy.fi.common.constant.LimitRelasetConstant;
import nckd.jimin.jyyy.fi.common.util.CommonUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

public class PersonReimQuotaHelper {

    /**
     * 作废个人额度表
     * @param filterList
     */
    public void doInvalidPersonReim(QFilter[] filterList){
        BizLog.log(String.format("作废条件范围内的个人额度表，过滤条件为：" + JSON.toJSONString(filterList)));

        DynamicObject[] invalidPersonReimArray = BusinessDataServiceHelper.load(BillTypeConstants.ER_REIMBURSEAMOUNT, "auditstatus", filterList);
        String idList = Arrays.stream(invalidPersonReimArray).map(personReim -> personReim.getString("id")).collect(Collectors.joining(";"));
        BizLog.log("作废的个人额度表数据为：" + idList);
        for(DynamicObject invalidPersonReim : invalidPersonReimArray){
            invalidPersonReim.set("auditstatus","2");
        }
        SaveServiceHelper.save(invalidPersonReimArray);
    }
    /**
     * 获取个人额度同步表 创建某个费用类型的个人额度
     * @param quotaVO
     * @return
     */
    public DynamicObject createPersonReimAmount(PersonReimQuotaVO  quotaVO){

        initQuotaYearAndMonth(quotaVO);
        // 通过[公司、费用类型、人员、币别、年度]判断是否已经创建个人额度表
        DynamicObject queryPersonAmount = QueryServiceHelper.queryOne(BillTypeConstants.ER_REIMBURSEAMOUNT, "id,nckd_sourcetype", new QFilter[]{
                new QFilter("company.id", QCP.equals, quotaVO.getCompanyId()),
                new QFilter("employee.id", QCP.equals, quotaVO.getUserId()),
                new QFilter("expenseitem.id", QCP.equals, quotaVO.getExpenseItemId()),
                new QFilter("currency.id", QCP.equals, quotaVO.getCurrencyId()),
                new QFilter("auditstatus", QCP.equals, "1"),
                new QFilter("dateyear", QCP.equals, String.valueOf(quotaVO.getYear()))
        });

        DynamicObject personAmountBill = BusinessDataServiceHelper.newDynamicObject(BillTypeConstants.ER_REIMBURSEAMOUNT);
        // 如果存在则从个人额度中复制
        if(queryPersonAmount != null){

            if(ReimAmountSourceTypeEnum.ER_REIMCTL_NEW.getKey().equals(queryPersonAmount.getString("nckd_sourcetype"))){
                BizLog.log(String.format("个人额度表【%s】已存在，且为手工新增，不予处理！", queryPersonAmount.getString("id")));
                return null;
            }
            boolean isNeedUpdate = copyModifyPersonReim(personAmountBill, queryPersonAmount.getLong("id"), quotaVO.getAmount(), quotaVO.getMonth());
            if(!isNeedUpdate){
                return null;
            }

        }else{
            createNewPersonReimAmount(personAmountBill,quotaVO);
        }

        BigDecimal totalAmount = BigDecimal.ZERO;
        // 计算年总额度
        for(int i = 1; i <= 12; i++) {
            totalAmount = BigDecimalUtil.add(totalAmount,personAmountBill.getBigDecimal("month" + i));
        }
        personAmountBill.set("totalamount", totalAmount);
        personAmountBill.set("auditstatus", "0");
        personAmountBill.set("nckd_sourcetype",quotaVO.getSourcetype().getKey());
        personAmountBill.set("nckd_sourcebillid",quotaVO.getSourcebillid());
        personAmountBill.set("nckd_limitrelaset",quotaVO.getLimitRelasetId());

        OperationResult saveOp = OperationServiceHelper.executeOperate("save", BillTypeConstants.ER_REIMBURSEAMOUNT, new DynamicObject[]{personAmountBill}, OperateOption.create());
        if(!saveOp.isSuccess() || saveOp.getSuccessPkIds().size() == 0){
            throw new KDBizException(CommonUtils.getOperationResultErrorInfos(saveOp));
        }
        OperationResult approveOp = OperationServiceHelper.executeOperate("approve", BillTypeConstants.ER_REIMBURSEAMOUNT, new Object[]{saveOp.getSuccessPkIds().get(0)}, OperateOption.create());
        if(!approveOp.isSuccess() || approveOp.getSuccessPkIds().size() == 0){
            throw new KDBizException(CommonUtils.getOperationResultErrorInfos(approveOp));
        }
        return personAmountBill;
    }

    protected DynamicObject getHrPersonInfo(Object userId){
        DynamicObject userInfo = BusinessDataServiceHelper.loadSingleFromCache(userId, "bos_user","number");
        // 查询人员的信息
        return QueryServiceHelper.queryOne(BillTypeConstants.HRPI_EMPPOSORGREL, "person.id,bsed", new QFilter[]{
                new QFilter("businessstatus", QCP.equals, "1"),
                new QFilter("iscurrentversion", QCP.equals, "1"),
                new QFilter("datastatus", QCP.equals, "1"),
                new QFilter("isprimary", QCP.equals, "1"),
                new QFilter("person.number", QCP.equals, userInfo.getString("number"))
        });
    }

    protected void initQuotaYearAndMonth(PersonReimQuotaVO  quotaVO){
        Calendar calendar = Calendar.getInstance();
        Date quotaDate = new Date();
        calendar.setTime(quotaDate);
        // 来源费用标准变更，次月生效
        if(ReimAmountSourceTypeEnum.STANDARDCHANGE.equals(quotaVO.getSourcetype())){
            quotaDate = CommonUtils.getFirstDayOfNextMonth(quotaDate);
            // 来源职级和岗位变动的，当月生效
        }else if(ReimAmountSourceTypeEnum.JOBLEVELCHANGE.equals(quotaVO.getSourcetype())
                || ReimAmountSourceTypeEnum.POSITIONCHANGE.equals(quotaVO.getSourcetype())){
            // 查询当年的额度
            DynamicObject queryPersonAmount = QueryServiceHelper.queryOne(BillTypeConstants.ER_REIMBURSEAMOUNT, "id,nckd_sourcetype", new QFilter[]{
                    new QFilter("company.id", QCP.equals, quotaVO.getCompanyId()),
                    new QFilter("employee.id", QCP.equals, quotaVO.getUserId()),
                    new QFilter("expenseitem.id", QCP.equals, quotaVO.getExpenseItemId()),
                    new QFilter("currency.id", QCP.equals, quotaVO.getCurrencyId()),
                    new QFilter("auditstatus", QCP.equals, "1"),
                    new QFilter("dateyear", QCP.equals, String.valueOf(calendar.get(Calendar.YEAR)))
            });
            if(queryPersonAmount != null){
                DynamicObject personAmountBill = BusinessDataServiceHelper.loadSingle(queryPersonAmount.get("id"), BillTypeConstants.ER_REIMBURSEAMOUNT);
                // 获取当前月份的
                BigDecimal curAmount = personAmountBill.getBigDecimal("month" + (calendar.get(Calendar.MONTH)+1));
                // 更新的额度如果小于当前额度，则次月生成
                if(quotaVO.getAmount().compareTo(curAmount) < 0){
                    quotaDate = CommonUtils.getFirstDayOfNextMonth(quotaDate);
                }
            }
            // 来源公司的变动，入职生效日期为额度创建时间
        } else if(ReimAmountSourceTypeEnum.COMPANYCHANGE.equals(quotaVO.getSourcetype())){
            DynamicObject personPositionInfo = getHrPersonInfo(quotaVO.getUserId());
            quotaDate = personPositionInfo.getDate("bsed");
            DynamicObject expenseItem = QueryServiceHelper.queryOne("er_expenseitemedit", "nckd_syncquota_type", new QFilter("id", QCP.equals, quotaVO.getExpenseItemId()).toArray());
            if("next".equals(expenseItem.getString("nckd_syncquota_type"))){
                quotaDate = CommonUtils.getFirstDayOfNextMonth(quotaDate);
            }
        }
        calendar.setTime(quotaDate);
        quotaVO.setYear(calendar.get(Calendar.YEAR));
        quotaVO.setMonth(calendar.get(Calendar.MONTH) + 1);
    }
    protected int getStartMonth(PersonReimQuotaVO  quotaVO , DynamicObject personAmountBill, DynamicObject personPositionInfo) {
        Calendar calendar = Calendar.getInstance();
        // 默认当前月
        int month = calendar.get(Calendar.MONTH) + 1;
        ReimAmountSourceTypeEnum sourcetype = quotaVO.getSourcetype();
        // 来源费用标准变更，次月生效
        if(ReimAmountSourceTypeEnum.STANDARDCHANGE.equals(sourcetype)){
            month = month+1;
        // 来源职级和岗位变动的，当月生效
        }else if(ReimAmountSourceTypeEnum.JOBLEVELCHANGE.equals(sourcetype) || ReimAmountSourceTypeEnum.POSITIONCHANGE.equals(sourcetype)){
            // 获取当前月份的
            BigDecimal curAmount = personAmountBill.getBigDecimal("month" + month);
            // 更新的额度如果小于当前额度，则次月生成
            if(quotaVO.getAmount().compareTo(curAmount) < 0){
                month = month+1;
            }
        // 来源公司的变动，入职生效日期为额度创建时间
        } else if(ReimAmountSourceTypeEnum.COMPANYCHANGE.equals(sourcetype)){
            Date bsedDate = personPositionInfo.getDate("bsed");
            Calendar bsedCalendar = Calendar.getInstance();
            bsedCalendar.setTime(bsedDate);
            month = calendar.get(Calendar.MONTH) + 1;
            DynamicObject expenseItem = QueryServiceHelper.queryOne("er_expenseitemedit", "nckd_syncquota_type", new QFilter("id", QCP.equals, quotaVO.getExpenseItemId()).toArray());
            if("next".equals(expenseItem.getString("nckd_syncquota_type"))){
                month = month+1;
            }
        }
        return month;
    }

    protected boolean copyModifyPersonReim(DynamicObject personAmountBill, Long copyPersonAmountBillId,BigDecimal amount, int startMonth) {
        DynamicObject oriPersonAmount = BusinessDataServiceHelper.loadSingle(copyPersonAmountBillId, BillTypeConstants.ER_REIMBURSEAMOUNT);

// 不同职级、相同额度时，如果没有新创建的，会作废掉现有的数据。因此调整逻辑，都需要创建
        // 如果月份之后的额度与需要更新的额度相同，则不保存
//        Boolean isNeedUpdate = false;
//        for(int i = startMonth; i <= 12; i++) {
//            if( amount != null && amount.compareTo(oriPersonAmount.getBigDecimal("month" + i)) != 0){
//                isNeedUpdate = true;
//                break;
//            }
//        }
//        if(!isNeedUpdate){
//            return false;
//        }

        Set<String> ignoreSet = new HashSet<>(Arrays.asList("id","creator","createtime","modifier","modifytime","auditor","auditdate","nckd_sourcetype","nckd_sourcebillid","nckd_limitrelaset"));
        DynamicObjectUtils.copy(oriPersonAmount,personAmountBill,ignoreSet);
        // 标准字段
        personAmountBill.set("wbsrcbilltype","er_reimctl_modify");
        personAmountBill.set("wbsrcbillid",oriPersonAmount.getPkValue());
        setPersonAmountData(personAmountBill,amount,startMonth);
        return true;
    }

    protected void createNewPersonReimAmount(DynamicObject personAmountBill , PersonReimQuotaVO  quotaVO){

        DynamicObject userInfo = BusinessDataServiceHelper.loadSingleFromCache(quotaVO.getUserId(), "bos_user");
        DynamicObject companyInfo = BusinessDataServiceHelper.loadSingleFromCache(quotaVO.getCompanyId(), "bos_org");
        DynamicObject expenseItemInfo = BusinessDataServiceHelper.loadSingleFromCache(quotaVO.getExpenseItemId(), "er_expenseitemedit");
        DynamicObject currencyInfo = BusinessDataServiceHelper.loadSingleFromCache(quotaVO.getCurrencyId(), "bd_currency");

        personAmountBill.set("company", companyInfo);
        personAmountBill.set("expenseitem", expenseItemInfo);
        personAmountBill.set("currency", currencyInfo);
        personAmountBill.set("dateyear", String.valueOf(quotaVO.getYear()));
        personAmountBill.set("costcompany", companyInfo);
        personAmountBill.set("amounttype", "1");
        personAmountBill.set("employee", userInfo);
        //personAmountBill.set("dept", reimburseQuota.get("dept.id"));
        personAmountBill.set("auditstatus", "0");
        personAmountBill.set("createtime", new Date());
        personAmountBill.set("modifytime", new Date());
        personAmountBill.set("creator", RequestContext.get().getCurrUserId());
        personAmountBill.set("modifier", RequestContext.get().getCurrUserId());
        personAmountBill.set("wbsrcbilltype", "er_reimctl_modify");
        setPersonAmountData(personAmountBill,quotaVO.getAmount(),quotaVO.getMonth());
    }

    public void syncReimLever(Long userId ,Long companyId,Long jobId){

        DynamicObject reimLever = getReimLever(jobId, companyId);
        if(reimLever != null){
            DynamicObject realReimSettingQuery = QueryServiceHelper.queryOne("er_reimbursesetting_rel", "id", new QFilter[]{
                    new QFilter("user", QCP.equals, userId),
                    new QFilter("company", QCP.equals, companyId)
            });
            // 存在则修改
            if(realReimSettingQuery != null){
                DynamicObject reimSettingInfo = BusinessDataServiceHelper.loadSingle(realReimSettingQuery.get("id"),"er_reimbursesetting_rel");
                DynamicObject reimburseLever = reimSettingInfo.getDynamicObject("reimburselevel");
                if(reimburseLever != null && reimburseLever.getString("id").equals(reimLever.getString("id"))){
                    // 职级未发生改变，直接返回
                    return;
                }

                reimSettingInfo.set("reimburselevel",reimLever.get("id"));
                SaveServiceHelper.save(new DynamicObject[]{ reimSettingInfo });
            }
        }
    }

    public DynamicObject getReimLever(Long jobId , Long companyId) {

        if(jobId == null || jobId == 0L || companyId == null || companyId == 0L){
            return null;
        }
        // 查询差旅级别
        List<QFilter> leverFilterList = new ArrayList<>();
        // 基础资料标准过滤条件
        leverFilterList.add(BaseDataServiceHelper.getBaseDataFilter("er_reimburselevel", companyId));
        leverFilterList.add(new QFilter("enable", QCP.equals,"1"));
        leverFilterList.add(new QFilter("nckd_joblevelhr.fbasedataid", QCP.equals,jobId));
        DynamicObject queryOne = QueryServiceHelper.queryOne("er_reimburselevel", "id", leverFilterList.toArray(new QFilter[0]));
        if(queryOne != null){
            return BusinessDataServiceHelper.loadSingleFromCache(queryOne.getLong("id"), "er_reimburselevel");
        }
        return null;
    }

    public DynamicObject getDefultReimLever() {
        // 查询差旅级别
        List<QFilter> leverFilterList = new ArrayList<>();
        // 基础资料标准过滤条件
        leverFilterList.add(new QFilter("enable", QCP.equals,"1"));
        leverFilterList.add(new QFilter("ispreset", QCP.equals,Boolean.TRUE));
        leverFilterList.add(new QFilter("number", QCP.equals,"General-01"));
        return QueryServiceHelper.queryOne("er_reimburselevel", "id", leverFilterList.toArray(new QFilter[0]));
    }
    /**
     * 对个人额度表的额度字段赋值
     * @param personAmountBill 个人额度表
     * @param amount 额度
     * @param startMonth 开始月份，新单则从0开始，非新单则从指定月份开始
     */
    protected void setPersonAmountData(DynamicObject personAmountBill , BigDecimal amount , int startMonth){

        for(int i = startMonth; i <= 12; i++) {

            personAmountBill.set("month" + i, amount);

        }
    }


    public void createQuotaJobleverChange(DynamicObject jobBakInfo, Map<Long, Map<Long, List<DynamicObject>>> limitRelasetExpenseItemMap, ReimAmountSourceTypeEnum sourcetype){
        DynamicObject joblever_new = jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_NEW);
        DynamicObject joblever_old = jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_OLD);

        List<DynamicObject> createQuotaList = new ArrayList<>();
        // 创建新职级下的个人额度
        for(Map.Entry<Long, Map<Long, List<DynamicObject>>> currencyRow : limitRelasetExpenseItemMap.entrySet()){
            // 币别ID
            Long currencyId = currencyRow.getKey();
            // 费用项目分组
            Map<Long, List<DynamicObject>> expenseItemGroupMap = currencyRow.getValue();

            for(Map.Entry<Long, List<DynamicObject>> expenseItemRow : expenseItemGroupMap.entrySet()){
                Long expenseItemId = expenseItemRow.getKey();
                List<DynamicObject> limitRelasetList = expenseItemRow.getValue();
                Optional<DynamicObject> findJobleverOp = limitRelasetList.stream().filter(r -> joblever_new.getPkValue()
                        .equals(r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_CLASSFIELD_JOBPOS).getPkValue())).findFirst();
                if(findJobleverOp.isPresent()){
                    BigDecimal quotaAmont = findJobleverOp.get().getBigDecimal(LimitRelasetConstant.KEY_NCKD_AMOUNT);
                    PersonReimQuotaVO personReimQuotaVO = new PersonReimQuotaVO(
                            jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_USER).getLong(JobPositionBakBillConstant.ID),
                            jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_ORG_NEW).getLong(JobPositionBakBillConstant.ID),
                            expenseItemId,
                            currencyId,
                            quotaAmont,
                            Optional.ofNullable(sourcetype).orElse(ReimAmountSourceTypeEnum.JOBLEVELCHANGE),
                            "",
                            findJobleverOp.get().getString(LimitRelasetConstant.ID));
                    createQuotaList.add(createPersonReimAmount(personReimQuotaVO));
                }

            }
        }

        if(joblever_old != null){
            List<Object> createReimList = createQuotaList.stream().filter(r -> !Objects.isNull(r)).map(r -> r.getPkValue()).collect(Collectors.toList());
            // 作废旧职级下，非新职级创建的个人额度数据
            for(Map.Entry<Long, Map<Long, List<DynamicObject>>> currencyRow : limitRelasetExpenseItemMap.entrySet()) {
                // 币别ID
                Long currencyId = currencyRow.getKey();
                // 费用项目分组
                Map<Long, List<DynamicObject>> expenseItemGroupMap = currencyRow.getValue();
                for(Map.Entry<Long, List<DynamicObject>> expenseItemRow : expenseItemGroupMap.entrySet()){
                    Long expenseItemId = expenseItemRow.getKey();
                    List<DynamicObject> limitRelasetList = expenseItemRow.getValue();
                    Optional<DynamicObject> findJobleverOp = limitRelasetList.stream().filter(r -> joblever_old.getPkValue()
                            .equals(r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_CLASSFIELD_JOBPOS).getPkValue())).findFirst();
                    if(findJobleverOp.isPresent()){
                        doInvalidPersonReim(new QFilter[]{
                                new QFilter("company.id", QCP.equals,jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_ORG_NEW).getLong(JobPositionBakBillConstant.ID)),
                                new QFilter("employee.id", QCP.equals, jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_USER).getLong(JobPositionBakBillConstant.ID)),
                                new QFilter("expenseitem.id", QCP.equals, expenseItemId),
                                new QFilter("currency.id", QCP.equals, currencyId),
                                new QFilter("auditstatus", QCP.equals, "1"),
                                new QFilter("id", QCP.not_in, createReimList)
                        });
                    }
                }
            }
        }

    }

    public void createQuotaPositionChange(DynamicObject jobBakInfo,Map<Long, Map<Long, List<DynamicObject>>> limitRelasetExpenseItemMap,ReimAmountSourceTypeEnum sourcetype){
        DynamicObject joblever_new = jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_JOBLEVEL_NEW);
        DynamicObject position_new = jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_POSITION_NEW);
        DynamicObject position_old = jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_POSITION_OLD);
        List<DynamicObject> createQuotaList = new ArrayList<>();
        // 创建新岗位下的额度
        for(Map.Entry<Long, Map<Long, List<DynamicObject>>> currencyRow : limitRelasetExpenseItemMap.entrySet()){
            // 币别ID
            Long currencyId = currencyRow.getKey();
            // 费用项目分组
            Map<Long, List<DynamicObject>> expenseItemGroupMap = currencyRow.getValue();

            for(Map.Entry<Long, List<DynamicObject>> expenseItemRow : expenseItemGroupMap.entrySet()){
                Long expenseItemId = expenseItemRow.getKey();
                List<DynamicObject> limitRelasetList = expenseItemRow.getValue();

                Optional<DynamicObject> findJobleverOp = limitRelasetList.stream().filter(r -> joblever_new.getPkValue()
                        .equals(r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_CLASSFIELD_JOBPOS).getPkValue())).findFirst();
                Optional<DynamicObject> findPositionOp = limitRelasetList.stream().filter(r -> position_new.getPkValue()
                        .equals(r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_CLASSFIELD_JOBPOS).getPkValue())).findFirst();

                // 人员岗位发生变化时，如果存在职级的费用标准，则不需要调整额度
                if(!findJobleverOp.isPresent() && findPositionOp.isPresent()){
                    BigDecimal quotaAmont = findPositionOp.get().getBigDecimal(LimitRelasetConstant.KEY_NCKD_AMOUNT);
                    PersonReimQuotaVO personReimQuotaVO = new PersonReimQuotaVO(
                            jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_USER).getLong(JobPositionBakBillConstant.ID),
                            jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_ORG_NEW).getLong(JobPositionBakBillConstant.ID),
                            expenseItemId,
                            currencyId,
                            quotaAmont,
                            Optional.ofNullable(sourcetype).orElse(ReimAmountSourceTypeEnum.POSITIONCHANGE),
                            "",
                            findPositionOp.get().getString(LimitRelasetConstant.ID));
                    createQuotaList.add(createPersonReimAmount(personReimQuotaVO));
                }
            }
        }
        if(position_old != null){
            List<Object> createQuotaIdList = createQuotaList.stream().filter(r -> !Objects.isNull(r)).map(r -> r.getPkValue()).collect(Collectors.toList());
            // 作废旧岗位下的额度
            for(Map.Entry<Long, Map<Long, List<DynamicObject>>> currencyRow : limitRelasetExpenseItemMap.entrySet()) {
                // 币别ID
                Long currencyId = currencyRow.getKey();
                // 费用项目分组
                Map<Long, List<DynamicObject>> expenseItemGroupMap = currencyRow.getValue();

                for (Map.Entry<Long, List<DynamicObject>> expenseItemRow : expenseItemGroupMap.entrySet()) {
                    Long expenseItemId = expenseItemRow.getKey();
                    List<DynamicObject> limitRelasetList = expenseItemRow.getValue();

                    Optional<DynamicObject> findJobleverOp = limitRelasetList.stream().filter(r -> joblever_new.getPkValue()
                            .equals(r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_CLASSFIELD_JOBPOS).getPkValue())).findFirst();
                    Optional<DynamicObject> findPositionOp = limitRelasetList.stream().filter(r -> position_old.getPkValue()
                            .equals(r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_CLASSFIELD_JOBPOS).getPkValue())).findFirst();
                    // 人员岗位发生变化时，如果存在职级的费用标准，则不需要作废
                    if (!findJobleverOp.isPresent() && findPositionOp.isPresent()) {
                        doInvalidPersonReim(new QFilter[]{
                                new QFilter("company.id", QCP.equals,jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_ORG_NEW).getLong(JobPositionBakBillConstant.ID)),
                                new QFilter("employee.id", QCP.equals, jobBakInfo.getDynamicObject(JobPositionBakBillConstant.KEY_NCKD_USER).getLong(JobPositionBakBillConstant.ID)),
                                new QFilter("expenseitem.id", QCP.equals, expenseItemId),
                                new QFilter("currency.id", QCP.equals, currencyId),
                                new QFilter("auditstatus", QCP.equals, "1"),
                                new QFilter("id",QCP.not_in,createQuotaIdList)
                        });
                    }
                }
            }
        }
    }

    public Map<Long, Map<Long, List<DynamicObject>>> getLimitRelasetMap() {
        Set<Long> bakBillIdSet = QueryServiceHelper.query(LimitRelasetConstant.ENTITYID, LimitRelasetConstant.ID, new QFilter[]{
                new QFilter(LimitRelasetConstant.KEY_STATUS, QFilter.equals, "C")
        }).stream().map(r -> r.getLong(JobPositionBakBillConstant.ID)).collect(Collectors.toSet());

        DynamicObject[] limitRelasetCol = BusinessDataServiceHelper.load(bakBillIdSet.toArray(), EntityMetadataCache.getDataEntityType(LimitRelasetConstant.ENTITYID));
        return Arrays.stream(limitRelasetCol)
                .collect(Collectors.groupingBy(
                        r -> r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_CURRENCY).getLong(LimitRelasetConstant.ID),
                        Collectors.groupingBy(r -> r.getDynamicObject(LimitRelasetConstant.KEY_NCKD_EXPENSEITEM).getLong(LimitRelasetConstant.ID)
                        )));
    }
}
