package com.dhcc.finance.main.service.impl;

import brave.Tracer;
import com.alibaba.fastjson.JSONArray;
import com.dhcc.common.Shift;
import com.dhcc.common.constant.FinanceStatusCode;
import com.dhcc.common.constant.SysConstants;
import com.dhcc.common.constant.SysStatusCode;
import com.dhcc.common.model.CurrencyMeta;
import com.dhcc.common.model.SysUserInfo;
import com.dhcc.common.model.response.RestfulResponse;
import com.dhcc.common.util.CacheDataUtil;
import com.dhcc.common.util.SnowflakeIdWorker;
import com.dhcc.finance.constant.FinanceDictConsts;
import com.dhcc.finance.constant.FinanceJymEnum;
import com.dhcc.finance.constant.MsConfigConsts;
import com.dhcc.finance.main.client.BatchTaskMonitorFeignClient;
import com.dhcc.finance.main.dao.*;
import com.dhcc.finance.main.domain.CwGlFreevalue;
import com.dhcc.finance.main.domain.*;
import com.dhcc.finance.main.model.*;
import com.dhcc.finance.main.service.CwGlVoucherService;
import com.dhcc.finance.main.service.CwGlVouchermaxnoService;
import com.dhcc.finance.main.service.FinanceForThirdService;
import com.dhcc.finance.main.service.FinanceForThirdSupplyService;
import com.dhcc.finance.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 功能描述：财务对外接口
 *
 * @author dml
 * @date 2019年5月22日 下午3:16:06
 * @修改日志：
 */
@Service
@Slf4j
public class FinanceForThirdServiceImple implements FinanceForThirdService {
    @Autowired
    private Tracer tracer;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private CwBdVouchtempMapper cwBdVouchtempMapper;// 凭证模板

    @Autowired
    private CwBdGlorgbookMapper cwBdGlorgbookMapper; // 帐套管理表

    @Autowired
    CwGlVouchermaxnoMapper cwGlVouchermaxnoMapper;// 最大凭证号

    @Autowired
    CwBdVouchtempBMapper cwBdVouchtempBMapper; // 凭证模板分录配置表

    @Autowired
    CwBdAccsubjMapper cwBdAccsubjMapper; // 会计科目

    @Autowired
    CwBdVouchtempFMapper CwBdVouchtempFMapper; // 凭证模板分录辅助配置表

    @Autowired
    CwGlVoucherService cwGlVoucherService; // 凭证信息服务

    @Autowired
    CwBdRelationMapper cwBdRelationMapper;// 凭证单据明细对应表

    @Autowired
    CwGlSettleMapper cwGlSettleMapper;// 结账表

    @Autowired
    CwGlVoucherMapper cwGlVoucherMapper;// 凭证信息表

    @Autowired
    CwBdSubjschemeMapper cwBdSubjschemeMapper;// 会计科目版本

    @Autowired
    CwGlTransferMapper cwGlTransferMapper;// 结转方案表

    @Autowired
    CwBdParametricMapper cwBdParametricMapper;// 财务参数化设置表

    @Autowired
    CwBdAccountingMapper cwBdAccountingMapper;// 人员设置表

    @Autowired
    CwBdScenarioMapper cwBdScenarioMapper;// 交易场景参数配置表

    @Autowired
    CwBdScenariorelationMapper cwBdScenariorelationMapper;// 交易场景凭证模板对应关系表

    @Autowired
    CwBdAccassitemMapper cwBdAccassitemMapper;// 辅助核算项目

    @Autowired
    AsDetailContractAssetsMapper asDetailContractAssetsMapper;// 合同资产明细

    @Autowired
    FinanceForThirdMapper financeForThirdMapper;// 三方接口DAO

    @Autowired
    CwBdRecordGlorgbookMapper cwBdRecordGlorgbookMapper;  // 自动建账记录表

    @Autowired
    CwBdRecordBatchMapper cwBdRecordBatchMapper;// 自动记录批次信息表

    @Autowired
    CwBdRecordSerialMapper cwBdRecordSerialMapper;// 自动记录批次流水信息表

    @Autowired
    FinanceForThirdSupplyService financeForThirdSupplyService; // 完善部分功能

    @Autowired
    CwGlBalanceMapper cwGlBalanceMapper;// 科目辅助余额表

    @Autowired
    CwBdScenariofieldMapper cwBdScenariofieldMapper;// 字段配置表

    @Autowired
    CwGlDetailMapper cwGlDetailMapper;// 凭证分录信息

    @Autowired
    PmProjectChildMapper PmProjectChildMapper;

    @Autowired
    CwNcAdvanceCostflowMapper cwNcAdvanceCostflowMapper;

    @Autowired
    CwNcAdvanceRequestMapper cwNcAdvanceRequestMapper;

    @Autowired
    BatchTaskMonitorFeignClient batchTaskMonitorFeignClient;

    @Autowired
    CwGlVouchermaxnoService cwGlVouchermaxnoService;

    @Autowired
    CwGlFreevalueMapper cwGlFreevalueMapper;// 凭证辅助信息
    
    @Autowired
    CwGlVoucherServiceImpl cwGlVoucherServiceImpl; // 凭证信息服务实现类


    //字段配置缓存
    private static Map<String, String> cacheMap = new ConcurrentHashMap<String, String>();

    private static Lock commitLock = new ReentrantLock();

    /*
     * (非 Javadoc)
     * Title: createVoucherInfo
     * Description:财务记账生成凭证接口
     * @param thirdBusiBenlistInfoList
     * @return
     * @see com.dhcc.finance.main.service.FinanceForThirdService#createVoucherInfo(java.util.List)
     * @author dml
     * @date 2019年5月22日 下午3:20:58
     * @修改日志：
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestfulResponse<Object, CurrencyMeta> createVoucherInfo(VoucherRequestInfo voucherRequestInfo) {
        // TODO 制单日期有的模块传了有的没传如果没有默认当前日期
        if (voucherRequestInfo.getPreparedate() == null) {
            voucherRequestInfo.setPreparedate(new Date());
        }
        // 根据交易码查询交易场景参数配置
        CwBdScenario cwBdScenario = cwBdScenarioMapper.selectByJym(voucherRequestInfo.getTradeCode());
        if (cwBdScenario == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
        }
        // 初始化缓存
        initScenariofield();
        // 查询流水信息
        List<FundsFlowInfo> thirdBusiBenlistInfoList = getFlowInfo(voucherRequestInfo, cwBdScenario);
        if (thirdBusiBenlistInfoList.isEmpty()) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.FUNDSFLOWINFO_IS_NULL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.FUNDSFLOWINFO_IS_NULL));
        }
        RestfulResponse<List<String>, CurrencyMeta> serialRes = financeForThirdSupplyService.insertRecordAccountForStart(thirdBusiBenlistInfoList, voucherRequestInfo, cwBdScenario.getFlowType(), cacheMap);//预先记录信息
        if (SysConstants.CODE.SUCCESS != serialRes.getCode().intValue()) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.SERIAL_ISNOT_REPEAT.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.SERIAL_ISNOT_REPEAT));//不允许流水重复记账
        }
        List<String> serialNoList = serialRes.getData();
        // 调用制单服务

        log.info("记账开始线程号>>>" + Thread.currentThread().getName() + "子项目号>>>" + voucherRequestInfo.getSubProjectCode());
        return startCreateVoucher(voucherRequestInfo, cwBdScenario, thirdBusiBenlistInfoList, serialNoList);
    }

    /**
     * 功能描述：开始制单
     *
     * @param voucherRequestInfo
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年7月31日 上午10:18:33
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> startCreateVoucher(VoucherRequestInfo voucherRequestInfo, CwBdScenario cwBdScenario,
                                                                     List<FundsFlowInfo> thirdBusiBenlistInfoList, List<String> serialNoList) {
        RestfulResponse<Object, CurrencyMeta> res = null;
        // 判断是否是特殊情况
        if (FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_TWO.equals(cwBdScenario.getAccountModel())) {
            // 受益权转让
            res = createVoucherForSpecialThree(thirdBusiBenlistInfoList, voucherRequestInfo, cwBdScenario, serialNoList);
        } else if (FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_THREE.equals(cwBdScenario.getAccountModel())) {
            // 受益权级别调整
            res = createVoucherForSpecialThree(thirdBusiBenlistInfoList, voucherRequestInfo, cwBdScenario, serialNoList);
        } else if (FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_EIGHT.equals(cwBdScenario.getAccountModel())) {
            // 受益权转让-模板
            res = createVoucherForSpecialEight(thirdBusiBenlistInfoList, voucherRequestInfo, cwBdScenario, serialNoList);
        } else if (FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_SIX.equals(cwBdScenario.getAccountModel())) {//财产权信托资产入账-非正常记账模式

            // 是否为保险金的情况
            if (("CJ3003".equals(voucherRequestInfo.getTradeCode()) || "CJ3006".equals(voucherRequestInfo.getTradeCode()))) {

                // 判断现金和非现金的总金额
                BigDecimal sum = new BigDecimal(0);
                BigDecimal sum2 = new BigDecimal(0);
                for (FundsFlowInfo data : thirdBusiBenlistInfoList) {
                    sum = sum.add(data.getJyfxjje() == null ? new BigDecimal(0) : data.getJyfxjje());
                    sum2 = sum2.add(data.getJyxjje() == null ? new BigDecimal(0) : data.getJyxjje());
                }
                boolean flag = sum.compareTo(new BigDecimal(0)) > 0;
                boolean flag2 = sum2.compareTo(new BigDecimal(0)) > 0;
                if (flag) {
                    // 资产凭证
                    List<AsDetailContractAssets> asDetailContractAssetsList = asDetailContractAssetsMapper.searchDetailListByPCH(voucherRequestInfo.getBatchNo());
                    res = createVoucherForSpecialSix(thirdBusiBenlistInfoList, asDetailContractAssetsList, voucherRequestInfo, serialNoList, cwBdScenario);
                }
                if ((!flag || SysConstants.CODE.SUCCESS == res.getCode()) && flag2) {
                    String voucherTemp = "";
                    FundsFlowInfo thirdBusiBenlistInfo = thirdBusiBenlistInfoList.get(0);

                    if ("1".equals(thirdBusiBenlistInfo.getDyjhbz())) {
                        // 单一
                        voucherTemp = "MB3001";
                    } else if ("2".equals(thirdBusiBenlistInfo.getDyjhbz())) {
                        voucherTemp = "MB3002";
                    }
                    // 资金凭证
                    RestfulResponse<Object, CurrencyMeta> resp = createVoucherInfoDetail(thirdBusiBenlistInfo, thirdBusiBenlistInfoList, cwBdScenario, voucherTemp, voucherRequestInfo, serialNoList);
                    if (res == null) {
                        res = resp;
                    }
                }
            } else {
                // 其他情况
                List<AsDetailContractAssets> asDetailContractAssetsList = asDetailContractAssetsMapper.searchDetailListByPCH(voucherRequestInfo.getBatchNo());
                res = createVoucherForSpecialSix(thirdBusiBenlistInfoList, asDetailContractAssetsList, voucherRequestInfo, serialNoList, cwBdScenario);
            }

        } else if (FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_FIVE.equals(cwBdScenario.getAccountModel())) {
            // 循环多条流水生成多条凭证   比如流水划付
            StringBuffer voucherKeys = new StringBuffer();
            for (FundsFlowInfo fundsFlowInfo : thirdBusiBenlistInfoList) {
                List<String> serialNo = new ArrayList<>();
                String serialPk = (String) FinancePublicUtil.getMethodValueNoexc(fundsFlowInfo, cacheMap.get(cwBdScenario.getFlowType() + "flowNo"));
                CwBdRecordSerial cwBdRecordSerial = cwBdRecordSerialMapper.searchIsSignTypeForSerial(serialPk, voucherRequestInfo.getTradeCode(), voucherRequestInfo.getBatchNo());
                if (cwBdRecordSerial != null && "1".equals(cwBdRecordSerial.getSignType())) {
                    continue;
                }
                serialNo.add(serialPk);
                RestfulResponse<Object, CurrencyMeta> result = createVoucherInfoOthers(fundsFlowInfo, thirdBusiBenlistInfoList, cwBdScenario, voucherRequestInfo, serialNo);
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("list", serialNo);
                map.put("batchNo", voucherRequestInfo.getBatchNo());
                map.put("tradecode", cwBdScenario.getJym());
                map.put("updateTime", new Date());
                if (SysConstants.CODE.SUCCESS != result.getCode().intValue()) {
                    map.put("failReason", result.getMsg());
                    map.put("signType", FinanceDictConsts.STATE.fail);
                    cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表
                    res = result;
                } else if (StringUtils.isNotBlank((String) result.getData())
                        && FinanceStatusCode.SCENARIO_NOT_CREATE_VOUCHER.message().equals(result.getData())) {
                    map.put("failReason", result.getData());
                    map.put("signType", FinanceDictConsts.STATE.success);
                    cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表
                    res = result;
                }
                if (thirdBusiBenlistInfoList.size() == 1) {
                    res = result;
                } else {
                    voucherKeys.append(result.getData());
                    if (thirdBusiBenlistInfoList.indexOf(fundsFlowInfo) + 1 < thirdBusiBenlistInfoList.size()) {
                        voucherKeys.append(",");
                    }
                }
            }
            if (res == null) {
                res = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, voucherKeys.toString(),
                        MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
            }
        } else if (FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_NINE.equals(cwBdScenario.getAccountModel())) {
            res = createVoucherForSpecialSeven(thirdBusiBenlistInfoList, voucherRequestInfo, cwBdScenario, serialNoList);
        } else {
            // 其他情况
            res = createVoucherInfoOthers(thirdBusiBenlistInfoList.get(0), thirdBusiBenlistInfoList, cwBdScenario, voucherRequestInfo, serialNoList);
        }
        if (!FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_FIVE.equals(cwBdScenario.getAccountModel())) {
            //若失败 则记录失败原因
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("list", serialNoList);
            map.put("batchNo", voucherRequestInfo.getBatchNo());
            map.put("tradecode", voucherRequestInfo.getTradeCode());
            map.put("updateTime", new Date());
            map.put("signType", FinanceDictConsts.STATE.success);
            if (SysConstants.CODE.SUCCESS != res.getCode().intValue()) {
                map.put("failReason", res.getMsg());
                map.put("signType", FinanceDictConsts.STATE.fail);
            } else if (StringUtils.isNotBlank((String) res.getData())
                    && FinanceStatusCode.SCENARIO_NOT_CREATE_VOUCHER.message().equals(res.getData())) {
                map.put("failReason", res.getData());
            }
            cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表
        }
        log.info("记账结束线程号>>>" + Thread.currentThread().getName() + "子项目号>>>" + voucherRequestInfo.getSubProjectCode());

        return res;
    }

    /**
     * 功能描述：生成凭证其他情况
     *
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param serialPkList
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年7月1日 下午9:55:55
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> createVoucherInfoOthers(FundsFlowInfo thirdBusiBenlistInfo,
                                                                          List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario, VoucherRequestInfo voucherRequestInfo,
                                                                          List<String> serialPkList) {
        // 业务数据非空校验
        if (thirdBusiBenlistInfo.chackData() != null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, thirdBusiBenlistInfo.chackData() + SysStatusCode.SERVER_CHECK_ERROR.message(),
                    MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_CHECK_ERROR));
        }
        // 如果是 CJ1012 CJ1015 是估值则进行在处理
        if (FinanceJymEnum.JDJXSRJT.code().equals(voucherRequestInfo.getTradeCode()) ||
                (FinanceJymEnum.JDJXFYZCJT.code().equals(voucherRequestInfo.getTradeCode()) && StringUtils.isNoneBlank((String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "fylx"))
                        && ArrayUtils.contains(FinanceDictConsts.FYLX.ALLFYLX, getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "fylx")))) {
            if (FinanceDictConsts.SF.yes.equals(getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "sfgz"))) {
              //  return handleDaily(thirdBusiBenlistInfo, thirdBusiBenlistInfoList, cwBdScenario, voucherRequestInfo, serialPkList);
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VALUATION_NOT_CREATE_VOUCHER.message(),
                       MetaDataUtil.getMeta(tracer, FinanceStatusCode.VALUATION_NOT_CREATE_VOUCHER));
            }
        }
        // 获取凭证模板编号
        String pkVouchtemp = getCwBdVouchtemp(thirdBusiBenlistInfo, cwBdScenario);
        if (StringUtils.isNoneBlank(pkVouchtemp)) {
            if ("MB0000".equals(pkVouchtemp)) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS,
                        SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, FinanceStatusCode.SCENARIO_NOT_CREATE_VOUCHER.message(),
                        MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
            }
            // 可能会一条流水生成多条凭证
            String[] pkArray = pkVouchtemp.split(",");
            RestfulResponse<Object, CurrencyMeta> result = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                    MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
            int flag = 0;
            for (String pk : pkArray) {
                RestfulResponse<Object, CurrencyMeta> res = createVoucherInfoDetail(thirdBusiBenlistInfo, thirdBusiBenlistInfoList, cwBdScenario, pk, voucherRequestInfo, serialPkList);
                if (SysConstants.CODE.FAIL == res.getCode().intValue()) {
                    ++flag;
                    if (pkArray.length > 1 && flag == pkArray.length) {
                        result = res;// 对于对应多个模板的记录下分录金额都为0的情况并返回
                    }
                    // 对于1对多的情况一条失败就抛出异常回滚
                    if (pkArray.length > 1 && !FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message().equals(res.getMsg())) {
                        throwNewException(res);
                    }
                }
                if (pkArray.length == 1) {
                    result = res;
                }
            }
//            // 判断是否估值  如果估值对部分场景做特殊处理
            if (FinanceDictConsts.SF.yes.equals(getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "sfgz"))) {
                return handleDailyReferenceCopy(thirdBusiBenlistInfo, thirdBusiBenlistInfoList, cwBdScenario, voucherRequestInfo, serialPkList);
            } else {
                return result;
            }
         //   return result;
        } else {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
        }
    }

    /**
     * 功能描述：手动抛出异常
     *
     * @param res void
     * @author dml
     * @date 2019年11月24日 下午3:34:34
     * @修改日志：
     */
    private void throwNewException(RestfulResponse<Object, CurrencyMeta> res) {
        String statusCode = res.getMeta().getStatusCode();
        FinanceStatusCode enumByKey = FinanceStatusCode.getEnumByKey(statusCode);
        if (enumByKey != null) {
            Shift.fatalThrow(enumByKey);
        } else {
            Shift.fatalThrow(SysStatusCode.OPERATION_FAIL);
        }
    }

    //流水中取实付金额
    //截取时间段内凭证最大、最小制单日期
    //判断日期是否重合，如果重合
    //判断实付金额是否等于应付金额，如果等于
    //如果不等于 ，差额等于实付减应付
    //日期如果不重合，获取凭证日期内的金额      获取未记账的日期的金额

    /**
     * 功能描述：结息收入计提时的凭证处理
     *
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param cwBdScenario
     * @param voucherRequestInfo
     * @param serialPkList
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author likai
     * @date 2020年6月12日 上午9:24:45
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> handleDaily(FundsFlowInfo thirdBusiBenlistInfo,
                                                              List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario,
                                                              VoucherRequestInfo voucherRequestInfo, List<String> serialPkList) {
        RestfulResponse<Object, CurrencyMeta> res = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
        // 查询账套信息
        CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByXtzxmbh((String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "xtzxmbh"));
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Map<String, Object> pri = new HashMap<>();
        Map<String, Object> val = new HashMap<>();
        CountInstestFeeModel countInstestFeeModel = new CountInstestFeeModel();
        // 结息收入 兑付
        if (voucherRequestInfo.getTradeCode().equals(FinanceJymEnum.JDJXSRJT.code())) {
            pri.put("jylsbh", thirdBusiBenlistInfo.getJylsbh());
            pri.put("jym", FinanceJymEnum.JDJXSRJT.code());
//          pri.put("sfzszzs", getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "sfzszzs"));
            Map<String, Date> preparedateFlow = cwGlDetailMapper.searchJxksr(pri);
            if (preparedateFlow == null || preparedateFlow.size() <= 0) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.JXRQ_IS_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.JXRQ_IS_NULL));
            }
            // 流水传入的最大、最小期间
            String preparedateMinFlow = format.format(preparedateFlow.get("preparedateMinFlow"));
            String preparedateMaxFlow = format.format(preparedateFlow.get("preparedateMaxFlow"));
            val.put("preparedateMin", preparedateMinFlow);
            val.put("preparedateMax", preparedateMaxFlow);
            val.put("xtzxmbh", thirdBusiBenlistInfo.getXtzxmbh());
            val.put("tradeCode", FinanceJymEnum.MRJT.code());
            // 查询期间内最大、最小制单日期
            Map<String, Date> preparedate = cwGlDetailMapper.searchPrepareDate(val);
            if (preparedate == null || preparedate.size() <= 0) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.PRRIOD_DATE_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.PRRIOD_DATE_NULL));
            }
            String preparedateMin = format.format(preparedate.get("preparedateMin"));
            String preparedateMax = format.format(preparedate.get("preparedateMax"));
            BlanceInfoLike blanceInfoLike = new BlanceInfoLike();
            countInstestFeeModel.setBatchType("2");
            countInstestFeeModel.setLoanId(thirdBusiBenlistInfo.getJjbh());
            countInstestFeeModel.setSubProjectId(thirdBusiBenlistInfo.getXtzxmbh());
            if (preparedateMin.compareTo(preparedateMinFlow) > 0 || preparedateMax.compareTo(preparedateMaxFlow) < 0) {
                if (preparedateMax.compareTo(preparedateMaxFlow) >= 0) {
                    try {
                        countInstestFeeModel.setStartDate(format.parse(preparedateMinFlow));
                        countInstestFeeModel.setEndDate(format.parse(FinanceDateUtil.getLastDay(preparedateMin, 1)));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    log.info("<><>><><>" + countInstestFeeModel);
                    RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> back = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);
                    blanceInfoLike = getBlanceInfo(cwBdGlorgbook, back.getData(), preparedateMin, preparedateMaxFlow);
                } else if (preparedateMin.compareTo(preparedateMinFlow) <= 0) {
                    try {
                        countInstestFeeModel.setStartDate(format.parse(FinanceDateUtil.getLastDay(preparedateMax, -1)));
                        countInstestFeeModel.setEndDate(format.parse(preparedateMaxFlow));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    log.info("<><>><><>" + countInstestFeeModel);
                    RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> back = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);
                    blanceInfoLike = getBlanceInfo(cwBdGlorgbook, back.getData(), preparedateMinFlow, preparedateMax);
                } else {
                    try {
                        countInstestFeeModel.setStartDate(format.parse(preparedateMinFlow));
                        countInstestFeeModel.setEndDate(format.parse(FinanceDateUtil.getLastDay(preparedateMin, 1)));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    log.info("<><>><><>" + countInstestFeeModel);
                    RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> back = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);

                    try {
                        countInstestFeeModel.setStartDate(format.parse(FinanceDateUtil.getLastDay(preparedateMax, -1)));
                        countInstestFeeModel.setEndDate(format.parse(preparedateMaxFlow));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    log.info("<><>><><>" + countInstestFeeModel);
                    RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> je = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);
                    blanceInfoLike = getBlanceSecond(cwBdGlorgbook, back.getData(), je.getData(), preparedateMin, preparedateMax);
                }
            }
            //   判断日期是否重合，如果重合
            if (preparedateMin.compareTo(preparedateMinFlow) <= 0 && preparedateMax.compareTo(preparedateMaxFlow) >= 0) {
                blanceInfoLike = getBlanceThird(cwBdGlorgbook, preparedateMinFlow, preparedateMaxFlow);
            }
            return handleDailyReference(thirdBusiBenlistInfo, thirdBusiBenlistInfoList,
                    cwBdScenario, voucherRequestInfo, serialPkList, cwBdGlorgbook, blanceInfoLike);
        }
        if (voucherRequestInfo.getTradeCode().equals(FinanceJymEnum.JDJXFYZCJT.code())) {
            pri.put("serialNo", thirdBusiBenlistInfo.getSerialNo());
            pri.put("jym", FinanceJymEnum.JDJXFYZCJT.code());
            Map<String, Date> preparedateFlow = cwGlDetailMapper.searchLastTransTime(pri);
            if (preparedateFlow == null || preparedateFlow.size() <= 0) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.JXRQ_IS_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.JXRQ_IS_NULL));
            }
            // 流水传入的最大、最小期间 
            String preparedateMinFlow = format.format(preparedateFlow.get("preparedateMinFlow"));
            String preparedateMaxFlow = format.format(preparedateFlow.get("preparedateMaxFlow"));
            val.put("preparedateMin", preparedateMinFlow);
            val.put("preparedateMax", preparedateMaxFlow);
            val.put("xtzxmbh", thirdBusiBenlistInfo.getSubProjectId());
            val.put("tradeCode", FinanceJymEnum.MRJTFY.code());
            // 查询期间内最大、最小制单日期
            Map<String, Date> preparedate = cwGlDetailMapper.searchPrepareDate(val);
            if (preparedate == null || preparedate.size() <= 0) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.PRRIOD_DATE_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.PRRIOD_DATE_NULL));
            }
            String preparedateMin = format.format(preparedate.get("preparedateMin"));
            String preparedateMax = format.format(preparedate.get("preparedateMax"));
            BigDecimal blanceFy = null;
            BigDecimal blance = null;
            BlanceInfoLike blanceInfoLike = new BlanceInfoLike();
            String fylx = (String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "fylx");
            // 判断是不是那几类费用
            if (StringUtils.isNoneBlank(fylx) && ArrayUtils.contains(FinanceDictConsts.FYLX.ALLFYLX, fylx)) {
                countInstestFeeModel.setBatchType("1");
                countInstestFeeModel.setFeeId(thirdBusiBenlistInfo.getIfiId());
                countInstestFeeModel.setSubProjectId(thirdBusiBenlistInfo.getSubProjectId());

                List<String> list = FinancePublicUtil.getFylx(fylx);
                if (preparedateMin.compareTo(preparedateMinFlow) > 0 || preparedateMax.compareTo(preparedateMaxFlow) < 0) {
                    if (preparedateMax.compareTo(preparedateMaxFlow) >= 0) {
                        try {
                            countInstestFeeModel.setStartDate(format.parse(preparedateMinFlow));
                            countInstestFeeModel.setEndDate(format.parse(FinanceDateUtil.getLastDay(preparedateMin, 1)));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        // 计算计提科目借方总额
                        blance = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMin, preparedateMaxFlow, false);
                        RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> back = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);
                        log.info("返回的金额-----------" + back.getData());
                        if (back.getData().getFeeAmount() != null) {
                            blanceFy = blance.add(back.getData().getFeeAmount());
                        } else {
                            blanceFy = blance;
                        }
                    } else if (preparedateMin.compareTo(preparedateMinFlow) <= 0) {
                        try {
                            countInstestFeeModel.setStartDate(format.parse(FinanceDateUtil.getLastDay(preparedateMax, -1)));
                            countInstestFeeModel.setEndDate(format.parse(preparedateMaxFlow));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        blance = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinFlow, preparedateMax, false);
                        RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> back = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);
                        log.info("返回的金额-----------" + back.getData());
                        if (back.getData().getFeeAmount() != null) {
                            blanceFy = blance.add(back.getData().getFeeAmount());
                        } else {
                            blanceFy = blance;
                        }
                    } else {
                        try {
                            countInstestFeeModel.setStartDate(format.parse(preparedateMinFlow));
                            countInstestFeeModel.setEndDate(format.parse(FinanceDateUtil.getLastDay(preparedateMin, 1)));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        blance = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMin, preparedateMax, false);
                        RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> back = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);
                        try {
                            countInstestFeeModel.setStartDate(format.parse(FinanceDateUtil.getLastDay(preparedateMax, -1)));
                            countInstestFeeModel.setEndDate(format.parse(preparedateMaxFlow));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        RestfulResponse<MoneyOfInstetstOrFee, CurrencyMeta> je = batchTaskMonitorFeignClient.countInstestFee(countInstestFeeModel);
                        if (back.getData().getFeeAmount() != null && je.getData().getFeeAmount() == null) {
                            blanceFy = blance.add(back.getData().getFeeAmount());
                        } else if (je.getData().getFeeAmount() != null && back.getData().getFeeAmount() == null) {
                            blanceFy = blance.add(je.getData().getFeeAmount());
                        } else if (back.getData().getFeeAmount() != null && je.getData().getFeeAmount() != null) {
                            blanceFy = blance.add(back.getData().getFeeAmount()).add(je.getData().getFeeAmount());
                        } else {
                            blanceFy = blance;
                        }
                        log.info("返回的金额-----------<><><><><><><>" + blanceFy);
                    }
                }
                //   判断日期是否重合，如果重合
                if (preparedateMin.compareTo(preparedateMinFlow) <= 0 && preparedateMax.compareTo(preparedateMaxFlow) >= 0) {
                    // 计算计提科目费用总额
                    blanceFy = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinFlow, preparedateMaxFlow, false);
                }
            }
            blanceInfoLike.setBlanceFy(blanceFy);
            return handleDailyReference(thirdBusiBenlistInfo, thirdBusiBenlistInfoList,
                    cwBdScenario, voucherRequestInfo, serialPkList, cwBdGlorgbook, blanceInfoLike);
        }
        return res;
    }

    /**
     * 功能描述：获取期间内收益、增值税、附加税
     *
     * @param cwBdGlorgbook
     * @param back
     * @param je
     * @param preparedateMinDate
     * @param preparedateMaxDate
     * @return BlanceInfoLike
     * @author likai
     * @date 2020年6月13日 上午11:24:41
     * @修改日志：
     */
    private BlanceInfoLike getBlanceThird(CwBdGlorgbook cwBdGlorgbook, String preparedateMinDate, String preparedateMaxDate) {
        List<String> list = new ArrayList<String>();
        // 余额科目
        list.add("113201");
        list.add("122199");
        BlanceInfoLike blanceInfoLike = new BlanceInfoLike();
        // 计算计提科目借方总额
        BigDecimal blanceSy = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, true);
        list.clear();
        list.add("22210601");
        BigDecimal blanceZzs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false);
        // 计提的附加税
        list.clear();
        list.add("222110");
        BigDecimal blanceFjs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false);
        blanceInfoLike.setBlanceFjs(blanceFjs);
        blanceInfoLike.setBlanceZzs(blanceZzs);
        blanceInfoLike.setBlanceSy(blanceSy);
        return blanceInfoLike;

    }

    /**
     * 功能描述：获取期间内收益、增值税、附加税,
     *
     * @param cwBdGlorgbook
     * @param back
     * @param je
     * @param preparedateMinDate
     * @param preparedateMaxDate
     * @return BlanceInfoLike
     * @author likai
     * @date 2020年6月13日 上午11:24:41
     * @修改日志：
     */
    private BlanceInfoLike getBlanceSecond(CwBdGlorgbook cwBdGlorgbook, MoneyOfInstetstOrFee back, MoneyOfInstetstOrFee je, String preparedateMinDate, String preparedateMaxDate) {
        List<String> list = new ArrayList<String>();
        // 余额科目
        list.add("113201");
        list.add("122199");
        BigDecimal blance = null;
        BigDecimal blanceSy = null;
        BigDecimal blanceZzs = null;
        BigDecimal blanceFjs = null;
        BlanceInfoLike blanceInfoLike = new BlanceInfoLike();
        blance = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, true);
        list.clear();
        list.add("22210601");
        if (back.getTaxAmount() != null && je.getTaxAmount() == null) {
            blanceZzs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false)
                    .add(back.getTaxAmount());

        } else if (je.getTaxAmount() != null && back.getTaxAmount() == null) {
            blanceZzs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false).add(je.getTaxAmount());
        } else if (back.getTaxAmount() != null && je.getTaxAmount() != null) {
            blanceZzs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false)
                    .add(back.getTaxAmount()).add(je.getTaxAmount());
        } else {
            blanceZzs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false);
        }
        // 计提的附加税
        list.clear();
        list.add("222110");
        if (back.getAddTaxAmount() != null && je.getAddTaxAmount() == null) {
            blanceFjs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false)
                    .add(back.getAddTaxAmount());
        } else if (je.getAddTaxAmount() != null && back.getAddTaxAmount() == null) {
            blanceFjs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false).add(je.getAddTaxAmount());
        } else if (back.getAddTaxAmount() != null && je.getAddTaxAmount() != null) {
            blanceFjs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false)
                    .add(back.getAddTaxAmount()).add(je.getAddTaxAmount());
        } else {
            blanceFjs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false);
        }
        if (back.getInterestAmount() != null && je.getInterestAmount() == null) {
            blanceSy = blance.add(back.getInterestAmount());
        } else if (je.getInterestAmount() != null && back.getInterestAmount() == null) {
            blanceSy = blance.add(je.getInterestAmount());
        } else if (back.getInterestAmount() != null && je.getInterestAmount() != null) {
            blanceSy = blance.add(back.getInterestAmount()).add(je.getInterestAmount());
        } else {
            blanceSy = blance;
        }
        blanceInfoLike.setBlanceFjs(blanceFjs);
        blanceInfoLike.setBlanceZzs(blanceZzs);
        blanceInfoLike.setBlanceSy(blanceSy);
        return blanceInfoLike;
    }

    /**
     * 功能描述：获取期间内收益、增值税、附加税,
     *
     * @param cwBdGlorgbook
     * @param moneyOfInstetstOrFee
     * @param preparedateMinDate
     * @param preparedateMaxDate
     * @return BlanceInfoLike
     * @author likai
     * @date 2020年6月13日 上午10:46:12
     * @修改日志：
     */
    private BlanceInfoLike getBlanceInfo(CwBdGlorgbook cwBdGlorgbook, MoneyOfInstetstOrFee moneyOfInstetstOrFee, String preparedateMinDate, String preparedateMaxDate) {
        List<String> list = new ArrayList<String>();
        // 余额科目
        list.add("113201");
        list.add("122199");
        BigDecimal blance = null;
        BigDecimal blanceSy = null;
        BigDecimal blanceZzs = null;
        BigDecimal blanceFjs = null;
        BlanceInfoLike blanceInfoLike = new BlanceInfoLike();
        blance = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, true);
        if (moneyOfInstetstOrFee.getInterestAmount() != null) {
            blanceSy = blance.add(moneyOfInstetstOrFee.getInterestAmount());
        } else {
            blanceSy = blance;
        }

        list.clear();
        list.add("22210601");
        if (moneyOfInstetstOrFee.getTaxAmount() != null) {
            blanceZzs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false).add(moneyOfInstetstOrFee.getTaxAmount());
        } else {
            blanceZzs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false);
        }
        // 计提的附加税
        list.clear();
        list.add("222110");
        if (moneyOfInstetstOrFee.getAddTaxAmount() != null) {
            blanceFjs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false).add(moneyOfInstetstOrFee.getAddTaxAmount());
        } else {
            blanceFjs = getBlanceCount(cwBdGlorgbook.getPkGlorgbook(), list, preparedateMinDate, preparedateMaxDate, false);
        }
        blanceInfoLike.setBlanceFjs(blanceFjs);
        blanceInfoLike.setBlanceZzs(blanceZzs);
        blanceInfoLike.setBlanceSy(blanceSy);
        return blanceInfoLike;
    }
    
    
    private RestfulResponse<Object, CurrencyMeta> handleDailyReferenceCopy(FundsFlowInfo thirdBusiBenlistInfo,
                                    List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario,
                                      VoucherRequestInfo voucherRequestInfo, List<String> serialPkList) {
        RestfulResponse<Object, CurrencyMeta> res = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
        // 结息收入 兑付
        if (voucherRequestInfo.getTradeCode().equals(FinanceJymEnum.JDJXSRJT.code())) {
            if (FinanceDictConsts.SF.yes.equals(getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "sfzszzs"))) {
                res = createVoucherInfoDetail(thirdBusiBenlistInfo, thirdBusiBenlistInfoList,
                        cwBdScenario, "MB1415", voucherRequestInfo, serialPkList);
            }
        }
        if (SysConstants.CODE.FAIL == res.getCode().intValue() && !FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message().equals(res.getMsg())) {
            throwNewException(res);
        }
        return res;
        
    }


    /**
     * 功能描述：对于受到每日计提影响的场景再做特殊处理
     *
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param cwBdScenario
     * @param pkVouchtemp
     * @param voucherRequestInfo
     * @param serialPkList
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年9月17日 下午2:55:42
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> handleDailyReference(FundsFlowInfo thirdBusiBenlistInfo,
                                                                       List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario,
                                                                       VoucherRequestInfo voucherRequestInfo, List<String> serialPkList, CwBdGlorgbook cwBdGlorgbook, BlanceInfoLike blanceInfoLike) {
        RestfulResponse<Object, CurrencyMeta> res = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
// TODO 每日计提不再生成差额凭证，如果定下可以删除
//      // 查询账套信息
//        CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByXtzxmbh((String)getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "xtzxmbh"));
        // 结息收入 兑付
        if (voucherRequestInfo.getTradeCode().equals(FinanceJymEnum.JDJXSRJT.code())) {
            new ArrayList<String>();
            // 余额科目
//          list.add("113201");
//          list.add("122199");
//          // 计算计提科目余额
//          BigDecimal blanceSy = getSubBlance(cwBdGlorgbook.getPkGlorgbook(), list, true); 
            // 判断实还的收益是 否大于计提科目余额
            // 小于等于
            if (thirdBusiBenlistInfo.getSy().compareTo(blanceInfoLike.getBlanceSy()) == 0) {
                // 判断是否应税
                if (FinanceDictConsts.SF.yes.equals(getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "sfzszzs"))) {
                    // 按实还收益比例 来计算，使用固定模板MB1415
                    res = createVoucherInfoDetail(thirdBusiBenlistInfo, thirdBusiBenlistInfoList,
                            cwBdScenario, "MB1415", voucherRequestInfo, serialPkList);
                }
            } else {
                // 大于 按待结转现有余额
                // 计提的增值税
//              list.clear();
//              list.add("22210601");
////            BigDecimal blanceZzs = getSubBlance(cwBdGlorgbook.getPkGlorgbook(), list, false);
//              // 计提的附加税
//              list.clear();
//              list.add("222110");
////            BigDecimal blanceFjs = getSubBlance(cwBdGlorgbook.getPkGlorgbook(), list, false);
                // 判断是否应税
                if (FinanceDictConsts.SF.yes.equals((String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "sfzszzs"))) {
                    // 新的流水信息
                    FundsFlowInfo newVal = new FundsFlowInfo();
                    BeanUtils.copyProperties(thirdBusiBenlistInfo, newVal);
                    newVal.setZzs(blanceInfoLike.getBlanceZzs());
                    newVal.setFjs(blanceInfoLike.getBlanceFjs());
                    // 按待结转现有余额
                    res = createVoucherInfoDetail(newVal, thirdBusiBenlistInfoList,
                            cwBdScenario, "MB1415", voucherRequestInfo, serialPkList);
                }
//              // 计算差额生成差额凭证
                BigDecimal syCe = thirdBusiBenlistInfo.getSy().subtract(blanceInfoLike.getBlanceSy());// 收益差额
                BigDecimal fjsCe = thirdBusiBenlistInfo.getFjs().subtract(blanceInfoLike.getBlanceFjs());// 附加税差额
                BigDecimal zzsCe = thirdBusiBenlistInfo.getZzs().subtract(blanceInfoLike.getBlanceZzs());// 增值税差额
                // 新的流水信息
                FundsFlowInfo newFlowInfo = new FundsFlowInfo();
                BeanUtils.copyProperties(thirdBusiBenlistInfo, newFlowInfo);
                // 对部分字段重新赋值
                newFlowInfo.setSy(syCe);// 收益差额
                newFlowInfo.setZzs(zzsCe);// 增值税差额
                newFlowInfo.setFjs(fjsCe);// 附加税差额
                newFlowInfo.setSfgz(FinanceDictConsts.SF.no);// 不估值

//              // 查询季度结息收入计提CJ1012的配置
                CwBdScenario cwBdScenarioRes = cwBdScenarioMapper.selectByJym(FinanceJymEnum.JDJXSRJT.code());
//              // 查询在CJ1012下对应的模板直接用该模板生成凭证
//              // 获取凭证模板编号
                String pkVouch = getCwBdVouchtemp(thirdBusiBenlistInfo, cwBdScenarioRes);
                String[] pkArray = pkVouch.split(",");
                RestfulResponse<Object, CurrencyMeta> res2 = null;
                for (String pk : pkArray) {
                    res2 = createVoucherInfoDetail(newFlowInfo, thirdBusiBenlistInfoList,
                            cwBdScenario, pk, voucherRequestInfo, serialPkList);
                    if (SysConstants.CODE.FAIL == res2.getCode().intValue() && !FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message().equals(res.getMsg())) {
                        Shift.fatalThrow(SysStatusCode.OPERATION_FAIL);//生成失败抛出异常
                    }
                }
                if (res == null || SysConstants.CODE.SUCCESS == res.getCode().intValue() || FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message().equals(res.getMsg())) {
                    res = res2;
                }
            }
        }
//      // 结息支出费用兑付 
        if (voucherRequestInfo.getTradeCode().equals(FinanceJymEnum.JDJXFYZCJT.code())) {
            String fylx = (String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "fylx");
            // 判断是不是那几类费用
            if (StringUtils.isNoneBlank(fylx) && ArrayUtils.contains(FinanceDictConsts.FYLX.ALLFYLX, fylx)) {
//              BigDecimal blanceFy = getSubBlance(cwBdGlorgbook.getPkGlorgbook(), list, false);
                // 如果实付费用大于
                if (thirdBusiBenlistInfo.getTransAmount().compareTo(blanceInfoLike.getBlanceFy()) != 0) {
                    BigDecimal syCe = thirdBusiBenlistInfo.getTransAmount().subtract(blanceInfoLike.getBlanceFy());// 费用差额
                    // 新的流水信息
                    FundsFlowInfo newFlowInfo = new FundsFlowInfo();
                    BeanUtils.copyProperties(thirdBusiBenlistInfo, newFlowInfo);
                    // 对部分字段重新赋值
                    newFlowInfo.setTransAmount(syCe);// 差额当费用
                    newFlowInfo.setIsAppraise(FinanceDictConsts.SF.no);// 估值为否

                    // 查询季度结息费用支出计提CJ1015的配置
                    CwBdScenario cwBdScenarioRes = cwBdScenarioMapper.selectByJym(FinanceJymEnum.JDJXFYZCJT.code());
                    // 查询在CJ1015下对应的模板直接用该模板生成凭证
                    // 获取凭证模板编号
                    String pkVouch = getCwBdVouchtemp(thirdBusiBenlistInfo, cwBdScenarioRes);
                    res = createVoucherInfoDetail(newFlowInfo, thirdBusiBenlistInfoList,
                            cwBdScenario, pkVouch, voucherRequestInfo, serialPkList);
                }
            }
        }
//      
        if (SysConstants.CODE.FAIL == res.getCode().intValue() && !FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message().equals(res.getMsg())) {
            throwNewException(res);//生成失败抛出异常
        }
        return res;
    }

    //  /**
//   * 功能描述：查询指定科目每日计提余额
//   * @param pkGlorgbook 账套主键
//   * @param list 科目集合
//   * @param isJie 是否借方科目
//   * @return BigDecimal
//   * @author dml
//   * @date 2019年9月18日 上午10:48:54
//   * @修改日志：
//   */
    private BigDecimal getSubBlance(String pkGlorgbook, List<String> list, boolean isJie) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", list);
        map.put("pkGlorgbook", pkGlorgbook);
        // 计算计提科目余额
        Map<String, BigDecimal> subBalanceCount = cwGlDetailMapper.subBalanceCount(map);
        BigDecimal blance;
        if (isJie) {
            blance = subBalanceCount.get("jieSum").subtract(subBalanceCount.get("daiSum"));
        } else {
            blance = subBalanceCount.get("daiSum").subtract(subBalanceCount.get("jieSum"));
        }
        return blance;
    }

    /**
     * 功能描述：查询指定科目每日计提余额
     *
     * @param pkGlorgbook 账套主键
     * @param list        科目集合
     * @param isJie       是否借方科目
     * @return BigDecimal
     * @author dml
     * @date 2019年9月18日 上午10:48:54
     * @修改日志：
     */
    private BigDecimal getBlanceCount(String pkGlorgbook, List<String> list, String preparedateMin, String preparedateMax, boolean isJie) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", list);
        map.put("pkGlorgbook", pkGlorgbook);
        map.put("preparedateMin", preparedateMin);
        map.put("preparedateMax", preparedateMax);
        // 计算计提科目余额
        Map<String, BigDecimal> subBalanceCount = cwGlDetailMapper.searchBalanceCount(map);
        BigDecimal blance;
        if (isJie) {
            blance = subBalanceCount.get("jieSum").subtract(subBalanceCount.get("daiSum"));
        } else {
            blance = subBalanceCount.get("daiSum").subtract(subBalanceCount.get("jieSum"));
        }
        return blance;
    }

    /**
     * 功能描述：生成凭证详情
     *
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param serialPkList
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年7月1日 下午9:55:55
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> createVoucherInfoDetail(FundsFlowInfo thirdBusiBenlistInfo,
                                                                          List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario,
                                                                          String pkVouchtemp, VoucherRequestInfo voucherRequestInfo, List<String> serialPkList) {
        // 根据凭证模板编号查询对应凭证模板信息
        CwBdVouchtemp cwBdVouchtemp = cwBdVouchtempMapper.selectByCode(pkVouchtemp);
        if (cwBdVouchtemp == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
        }
        // 查询账套信息
        CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByXtzxmbh((String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "xtzxmbh"));
        if (cwBdGlorgbook == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.GLORGBOOK_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.GLORGBOOK_MISMATCH));
        }
        //制单人用录入人员
        String userId = (String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "lrry");
        // 获取会计期间
        String periodNow = FinanceDateUtil.getPeriod(voucherRequestInfo.getPreparedate());
        // 如果已记账则获取下一个会计期间
        String period = getPeriod(cwBdGlorgbook.getPkGlorgbook(), periodNow);


        // 新增制单实体类
        // 设置凭证信息实体参数
        CwGlVoucherWeb cwGlVoucherWeb = new CwGlVoucherWeb();
        // 两个表字段不一样先暂时去有数的那条
        String fqmjbh = (String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "fqmjbh");
        cwGlVoucherWeb.setFqmjbh(fqmjbh);
        cwGlVoucherWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
        cwGlVoucherWeb.setPkVoucherty(cwBdVouchtemp.getPkVouchertype());
        if (FinanceJymEnum.MRJT.code().equals(cwBdScenario.getJym()) || FinanceJymEnum.MRJTFY.code().equals(cwBdScenario.getJym())) {
            cwGlVoucherWeb.setPkSystem(FinanceDictConsts.LYXT.MRJT);
        } else if (FinanceJymEnum.DKTZHCZJ.code().equals(cwBdScenario.getJym()) && FinanceDictConsts.LYXT.XJXT.equals(thirdBusiBenlistInfo.getSjly())) {
            cwGlVoucherWeb.setPkSystem(FinanceDictConsts.LYXT.XJXT);
        } else if (FinanceJymEnum.JDJXSRJT.code().equals(cwBdScenario.getJym()) && FinanceDictConsts.LYXT.XJXT.equals(thirdBusiBenlistInfo.getSjly())) {
            cwGlVoucherWeb.setPkSystem(FinanceDictConsts.LYXT.XJXT);
        } else if (FinanceJymEnum.JDJXSRDZ.code().equals(cwBdScenario.getJym()) && FinanceDictConsts.LYXT.XJXT.equals(thirdBusiBenlistInfo.getSjly())) {
            cwGlVoucherWeb.setPkSystem(FinanceDictConsts.LYXT.XJXT);
        } else {
            cwGlVoucherWeb.setPkSystem(cwBdVouchtemp.getSrcsystem());
        }
        cwGlVoucherWeb.setVouchertype(FinanceDictConsts.Cwpzzt.YZD);
        cwGlVoucherWeb.setPkPrepared(userId);
        cwGlVoucherWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        cwGlVoucherWeb.setPeriod(period);
        String abstracts = getAbstracts(thirdBusiBenlistInfo, cwBdScenario, cwBdVouchtemp.getAbstracts());
        cwGlVoucherWeb.setAbstracts(abstracts);// 摘要
        // 设置业务发生日期
        cwGlVoucherWeb.setOccDate((Date) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, "jysj"));
        // 设置交易码
        cwGlVoucherWeb.setTradecode(voucherRequestInfo.getTradeCode());
        // 用于存放凭证分录信息
        List<CwGlDetailWeb> cwGlDetailList = new ArrayList<CwGlDetailWeb>();
        // 查询凭证模板分录配置表
        RestfulResponse<Object, CurrencyMeta> detailInfo = getDetailInfo(cwGlVoucherWeb, cwGlDetailList, thirdBusiBenlistInfo, thirdBusiBenlistInfoList,
                cwBdScenario, cwBdVouchtemp);
        if (SysConstants.CODE.FAIL == detailInfo.getCode().intValue()) {
            return detailInfo;
        }
        if (cwGlDetailList.size() == 0) {//分录上的金额借贷都为零
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL));
        }
        // 计算借方合计和贷方合计
        BigDecimal totaldebit = new BigDecimal("0"), totalcredit = new BigDecimal("0");
        for (CwGlDetailWeb cwGlDetailWeb : cwGlDetailList) {
            totaldebit = totaldebit.add(cwGlDetailWeb.getLocaldebitamount());
            totalcredit = totalcredit.add(cwGlDetailWeb.getLocalcreditamount());
            // 给分录设置账套主键和制单日期
            cwGlDetailWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
            cwGlDetailWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        }
        // 借贷平衡判断
        if (totaldebit.compareTo(totalcredit) != 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.LOAN_NOT_BALANCE.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.LOAN_NOT_BALANCE));
        }
        cwGlVoucherWeb.setTotaldebit(totaldebit);// 借方合计
        cwGlVoucherWeb.setTotalcredit(totalcredit);// 贷方合计
        cwGlVoucherWeb.setCwGlDetailList(cwGlDetailList);// 分录信信息

        // 获取当前最大凭证号

        CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoService.getVoucherMaxNo(cwBdGlorgbook.getPkGlorgbook(), period);
        if (cwGlVouchermaxno == null || StringUtils.isBlank(cwGlVouchermaxno.getMaxno())) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.MAXNO_INFO_NOTFOUND.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.MAXNO_INFO_NOTFOUND));
        }

        // 凭证号
        String voucherno = Integer.valueOf(cwGlVouchermaxno.getMaxno()) + 1 + "";
        cwGlVoucherWeb.setVoucherno(voucherno);

        // 调用新增凭证服务
        RestfulResponse<Object, CurrencyMeta> addCwGlVoucher = cwGlVoucherService.addCwGlVoucher(cwGlVoucherWeb);
        // 新增凭证单据明细对应关系等
        if (SysConstants.CODE.SUCCESS == addCwGlVoucher.getCode().intValue()) {
            //生产凭证后 更新记录表
            Map<String, Object> map = new HashMap<String, Object>();//流水记录表
            String pkVoucher = (String) addCwGlVoucher.getData();

            String serialNo = (String) FinancePublicUtil.getMethodValueNoexc(thirdBusiBenlistInfo, cacheMap.get(cwBdScenario.getFlowType() + "flowNo"));
            List<String> voucherList = cwBdRecordSerialMapper.selectCwBdRecordSerialByBatchNo(voucherRequestInfo.getBatchNo(), cwBdScenario.getJym(), serialNo);
            if (voucherList.size() == 1 && StringUtils.isNoneBlank(voucherList.get(0))) {
                map.put("pkVoucher", voucherList.get(0) + "," + pkVoucher);
            } else {
                map.put("pkVoucher", pkVoucher);
            }
            map.put("list", serialPkList);
            map.put("signType", FinanceDictConsts.STATE.success);
            map.put("batchNo", voucherRequestInfo.getBatchNo());
            map.put("tradecode", cwBdScenario.getJym());
            map.put("failReason", "");
            map.put("updateTime", new Date());
            cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表

            CwBdRelation cwBdRelation = new CwBdRelation();
            cwBdRelation.setPkRelation(SnowflakeIdWorker.getInstance().nextIdString());
            cwBdRelation.setPkSrcbilltype(cwBdVouchtemp.getPkBilltype());
            cwBdRelation.setPkSrcbillpk(thirdBusiBenlistInfo.getId());
            cwBdRelation.setPkVoucher((String) addCwGlVoucher.getData());
            cwBdRelation.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
            cwBdRelation.setCreateUser(userId);
            cwBdRelation.setCreateTime(new Date());
            // 新增凭证单据明细对应关系
            cwBdRelationMapper.insert(cwBdRelation);
            // 自动审核记账(自动审核记账失败不影响整体功能)
            try {
                automaticAuditAndSign(addCwGlVoucher, cwGlVoucherWeb, userId, map);
            } catch (Exception e) {
                log.error("自动审核记账异常>>>>>>>>>", e);
            }
        }
        return addCwGlVoucher;
    }


    /**
     * 功能描述：获取动态摘要
     *
     * @param thirdBusiBenlistInfo
     * @param abstracts
     * @return String
     * @author dml
     * @date 2019年12月16日 下午3:53:54
     * @修改日志：
     */
    private String getAbstracts(FundsFlowInfo thirdBusiBenlistInfo, CwBdScenario cwBdScenario, String abstracts) {
        if (StringUtils.isBlank(abstracts) || !abstracts.contains("${")) {
            return abstracts;
        }
        String exp = abstracts.substring(abstracts.indexOf("$"), abstracts.indexOf("}") + 1);
        String fieldValue = (String) getFieldValue(thirdBusiBenlistInfo, cwBdScenario, exp);
        String res = abstracts.replace(exp, fieldValue);
        return getAbstracts(thirdBusiBenlistInfo, cwBdScenario, res);
    }

    /**
     * 功能描述：获取分录信息
     *
     * @param cwGlDetailList
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param cwBdScenario
     * @param cwBdVouchtemp
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年7月8日 下午2:52:48
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> getDetailInfo(CwGlVoucherWeb cwGlVoucherWeb, List<CwGlDetailWeb> cwGlDetailList, FundsFlowInfo thirdBusiBenlistInfo,
                                                                List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario, CwBdVouchtemp cwBdVouchtemp) {
        // 查询凭证分录
        List<CwBdVouchtempB> cwBdVouchtempBList = cwBdVouchtempBMapper.selectByPkVouchtemp(cwBdVouchtemp.getPkVouchtemp());
        for (CwBdVouchtempB cwBdVouchtempB : cwBdVouchtempBList) {
            // 循环分录组装分录信息
            RestfulResponse<Object, CurrencyMeta> setCwGlDetailWeb = null;
            if (FinanceDictConsts.Syzt.EFFECTIVE.equals(cwBdVouchtempB.getMultipleType())) {
                // 分录可循环的情况
                setCwGlDetailWeb = setCwGlDetailWebList(cwGlVoucherWeb, cwGlDetailList, thirdBusiBenlistInfoList, cwBdScenario, cwBdVouchtempB);
            } else {
                // 正常情况
                setCwGlDetailWeb = setCwGlDetailWeb(cwGlVoucherWeb, cwGlDetailList, thirdBusiBenlistInfo, thirdBusiBenlistInfoList, cwBdScenario, cwBdVouchtempB);
            }
            if (SysConstants.CODE.FAIL == setCwGlDetailWeb.getCode().intValue()) {
                return setCwGlDetailWeb;
            }
        }
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * 功能描述：设置分录及其辅助项(分录可循环的)
     *
     * @param cwGlDetailList
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param cwBdScenario
     * @param cwBdVouchtemp
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年7月6日 下午2:18:17
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> setCwGlDetailWebList(CwGlVoucherWeb cwGlVoucherWeb, List<CwGlDetailWeb> cwGlDetailList,
                                                                       List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario, CwBdVouchtempB cwBdVouchtempB) {
        CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectByPrimaryKey(cwBdVouchtempB.getPkAccsubj());
        List<CwBdVouchtempF> cwBdVouchtempFList = CwBdVouchtempFMapper.selectByPkVouchtempB(cwBdVouchtempB.getPkVouchtempB());
        for (FundsFlowInfo fundsFlowInfo : thirdBusiBenlistInfoList) {
            // 表达式计算参数
            Map<String, Object> map = getParmMap(cwGlVoucherWeb, cwGlDetailList, fundsFlowInfo, thirdBusiBenlistInfoList,
                    cwBdScenario, cwBdVouchtempB, cwBdAccsubj.getSubjcode());
            // 原币金额
            BigDecimal orimoney;
            // 如果公式直接在map存在 即公式为单个字段
            if (map.containsKey(cwBdVouchtempB.getOrimoney())) {
                Object obj = map.get(cwBdVouchtempB.getOrimoney());
                if (obj instanceof BigDecimal) {
                    orimoney = (BigDecimal) obj;
                } else if (obj instanceof String) {
                    orimoney = new BigDecimal((String) obj);
                } else
                    orimoney = null;
            } else {
                // 公式存在计算走三方接口
                orimoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getOrimoney(), map);
            }
            // 本币金额  默认与原币金额相同
            BigDecimal basemoney = orimoney;
            if (!cwBdVouchtempB.getOrimoney().equals(cwBdVouchtempB.getBasemoney())) {
                // 公式不同时重新计算
                if (map.containsKey(cwBdVouchtempB.getBasemoney())) {
                    Object obj = map.get(cwBdVouchtempB.getBasemoney());
                    if (obj instanceof BigDecimal) {
                        basemoney = (BigDecimal) obj;
                    } else if (obj instanceof String) {
                        basemoney = new BigDecimal((String) obj);
                    } else
                        basemoney = null;
                } else {
                    // 公式存在计算走三方接口
                    basemoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getBasemoney(), map);
                }
            }
            if (orimoney == null || basemoney == null) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                        FinanceStatusCode.EXP_CALCULATION_FAILURE.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.EXP_CALCULATION_FAILURE));
            }
            // 凭证分录信息实体
            CwGlDetailWeb cwGlDetailWeb = new CwGlDetailWeb();
            String abstracts = getAbstracts(fundsFlowInfo, cwBdScenario, cwBdVouchtempB.getAbstracts());
            cwGlDetailWeb.setAbstracts(abstracts);
            cwGlDetailWeb.setPkAccsubj(cwBdAccsubj.getPkAccsubj());
            cwGlDetailWeb.setSubjcode(cwBdAccsubj.getSubjcode());// 必传
            cwGlDetailWeb.setSubjname(cwBdAccsubj.getSubjname());
            cwGlDetailWeb.setPkCurrtype(cwBdVouchtempB.getPkCurrtype());
            if (FinanceDictConsts.Cwjdfx.JIE.equals(cwBdVouchtempB.getDirection())) {
                cwGlDetailWeb.setDebitamount(orimoney);
                cwGlDetailWeb.setLocaldebitamount(basemoney);
                cwGlDetailWeb.setCreditamount(new BigDecimal("0"));
                cwGlDetailWeb.setLocalcreditamount(new BigDecimal("0"));
            } else {
                cwGlDetailWeb.setDebitamount(new BigDecimal("0"));
                cwGlDetailWeb.setLocaldebitamount(new BigDecimal("0"));
                cwGlDetailWeb.setCreditamount(orimoney);
                cwGlDetailWeb.setLocalcreditamount(basemoney);
            }
            List<CwGlFreevalue> cwGlFreevalueList = new ArrayList<CwGlFreevalue>();
            // 查询凭证模板分录辅助配置
            for (CwBdVouchtempF cwBdVouchtempF : cwBdVouchtempFList) {
                CwGlFreevalue cwGlFreevalue = new CwGlFreevalue();
                cwGlFreevalue.setChecktype(cwBdVouchtempF.getPkAccass());
                // 获得辅助值
                String methodValue = null;
                try {
                    // 辅助值(可能有判断条件)
                    String assvalue = getAssValue(cwBdVouchtempF, fundsFlowInfo);
                    if (StringUtils.isBlank(assvalue)) {// 如果为空则跳过
                        continue;
                    }
                    methodValue = (String) FinancePublicUtil.getMethodValue(fundsFlowInfo, assvalue);
                } catch (Exception e) {
                    log.error("获取辅助值失败>>>>>>>>>", e);
                }
                if (StringUtils.isBlank(methodValue)) {
                    return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, cwBdVouchtempF.getAssvalue() + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
                            MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
                }
                cwGlFreevalue.setCheckvalue(methodValue);
                cwGlFreevalueList.add(cwGlFreevalue);
            }
            cwGlDetailWeb.setCwGlFreevalueList(cwGlFreevalueList);// 辅助信息
            // TODO 如果分录金额为0就过滤掉(先按这种模式来)
            if (cwGlDetailWeb.getLocalcreditamount().compareTo(BigDecimal.ZERO) != 0 || cwGlDetailWeb.getLocaldebitamount().compareTo(BigDecimal.ZERO) != 0) {
                cwGlDetailList.add(cwGlDetailWeb);
            }
        }
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * 功能描述：获取表达式所需参数值
     *
     * @param cwGlVoucherWeb
     * @param cwGlDetailList
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param cwBdScenario
     * @param cwBdVouchtempB
     * @param subjcode
     * @return Map<String, Object>
     * @author dml
     * @date 2019年9月25日 下午2:45:30
     * @修改日志：
     */
    private Map<String, Object> getParmMap(CwGlVoucherWeb cwGlVoucherWeb, List<CwGlDetailWeb> cwGlDetailList, FundsFlowInfo thirdBusiBenlistInfo,
                                           List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario, CwBdVouchtempB cwBdVouchtempB, String subjcode) {
        // 表达式计算参数
        Map<String, Object> map = new HashMap<>();
        map.put("DWJZ", thirdBusiBenlistInfo.getDwjz() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getDwjz());
        map.put("JYJE", thirdBusiBenlistInfo.getJyje() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getJyje());
        map.put("JYFE", thirdBusiBenlistInfo.getJyfe() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getJyfe());
        map.put("JYFY", thirdBusiBenlistInfo.getJyfy() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getJyfy());
        map.put("SYJE", thirdBusiBenlistInfo.getSyje() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getSyje());
        map.put("BJ", thirdBusiBenlistInfo.getBj() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getBj());
        map.put("SY", thirdBusiBenlistInfo.getSy() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getSy());
        map.put("FY", thirdBusiBenlistInfo.getFy() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getFy());
        map.put("TRANS_AMOUNT", thirdBusiBenlistInfo.getTransAmount() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getTransAmount());
        map.put("ADDED_TAX", thirdBusiBenlistInfo.getAddedTax() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getAddedTax());
        map.put("ZZS", thirdBusiBenlistInfo.getZzs() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getZzs());
        map.put("FJS", thirdBusiBenlistInfo.getFjs() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getFjs());
        map.put("ZZJE", thirdBusiBenlistInfo.getZzje() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getZzje());
        map.put("ZZFE", thirdBusiBenlistInfo.getZzfe() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getZzfe());
        map.put("instetst_amount", thirdBusiBenlistInfo.getInstetstAmount() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getInstetstAmount());
        map.put("tax_amount", thirdBusiBenlistInfo.getTaxAmount() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getTaxAmount());
        map.put("HKJE", thirdBusiBenlistInfo.getHkje() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getHkje());
        map.put("DFSYK", thirdBusiBenlistInfo.getDfsyk() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getDfsyk());
        map.put("YSLX", thirdBusiBenlistInfo.getYslx() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getYslx());
        map.put("JYXJJE", thirdBusiBenlistInfo.getJyxjje() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getJyxjje());
        map.put("JYXJFE", thirdBusiBenlistInfo.getJyxjfe() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getJyxjfe());
        map.put("JYFXJJE", thirdBusiBenlistInfo.getJyfxjje() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getJyfxjje());
        map.put("JYFXJFE", thirdBusiBenlistInfo.getJyfxjfe() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getJyfxjfe());
        map.put("BFRZJE", thirdBusiBenlistInfo.getBfrzje() == null ? new BigDecimal("0") : thirdBusiBenlistInfo.getBfrzje());
        // 特殊情况多条流水但是分录不循环,并且一次来的多条流水是生成一条凭证才能标注为4
        // 这种情况下不循环的分录要将流水求和再计算
        if (FinanceDictConsts.ACCOUNT_MODEL.ACCOUNT_MODEL_FOUR.equals(cwBdScenario.getAccountModel())
                && FinanceDictConsts.Syzt.INVALID.equals(cwBdVouchtempB.getMultipleType())) {
            // 根据定好的规则  先算交易金额交易份额的的总和，损益平准金比例再按公式计算值
            BigDecimal jyje = new BigDecimal("0"), jyfe = new BigDecimal("0"), syje = new BigDecimal("0"),
                    zzje = new BigDecimal("0"), zzfe = new BigDecimal("0");
            for (FundsFlowInfo fundsFlowInfo : thirdBusiBenlistInfoList) {
                jyje = jyje.add(fundsFlowInfo.getJyje() == null ? new BigDecimal("0") : fundsFlowInfo.getJyje());
                jyfe = jyfe.add(fundsFlowInfo.getJyfe() == null ? new BigDecimal("0") : fundsFlowInfo.getJyfe());
                syje = syje.add(fundsFlowInfo.getSyje() == null ? new BigDecimal("0") : fundsFlowInfo.getSyje());
                zzje = zzje.add(fundsFlowInfo.getZzje() == null ? new BigDecimal("0") : fundsFlowInfo.getZzje());
                zzfe = zzfe.add(fundsFlowInfo.getZzfe() == null ? new BigDecimal("0") : fundsFlowInfo.getZzfe());
            }
            map.put("JYJE", jyje);
            map.put("JYFE", jyfe);
            map.put("SYJE", syje);
            map.put("ZZJE", zzje);
            map.put("ZZFE", zzfe);
        }
        //TODO 损益平准金属于特殊情况  这用的科目编码判断    损益平准金比例sql要改
        if (subjcode.startsWith("4003")) {
            BigDecimal proportion = getProportion(cwGlVoucherWeb.getPkGlorgbook(), cwGlVoucherWeb.getPeriod());//损益平准金比例
            map.put("SYPZJBL", proportion);
        }
        return map;
    }

    /**
     * 功能描述：设置分录及其辅助项（正常情况）
     *
     * @param cwGlDetailList
     * @param thirdBusiBenlistInfo
     * @param thirdBusiBenlistInfoList
     * @param cwBdScenario
     * @param cwBdVouchtemp
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年7月6日 下午2:18:17
     * @修改日志：20200616 优化本币金额和原币金额的计算逻辑 lxj
     */
    private RestfulResponse<Object, CurrencyMeta> setCwGlDetailWeb(CwGlVoucherWeb cwGlVoucherWeb, List<CwGlDetailWeb> cwGlDetailList, FundsFlowInfo thirdBusiBenlistInfo,
                                                                   List<FundsFlowInfo> thirdBusiBenlistInfoList, CwBdScenario cwBdScenario, CwBdVouchtempB cwBdVouchtempB) {
        // 查询对应科目详情
        CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectByPrimaryKey(cwBdVouchtempB.getPkAccsubj());
        // 获取表达式参数
        Map<String, Object> map = getParmMap(cwGlVoucherWeb, cwGlDetailList, thirdBusiBenlistInfo, thirdBusiBenlistInfoList,
                cwBdScenario, cwBdVouchtempB, cwBdAccsubj.getSubjcode());
        // 原币金额
        BigDecimal orimoney;
        // 如果公式直接在map存在 即公式为单个字段
        if (map.containsKey(cwBdVouchtempB.getOrimoney())) {
            Object obj = map.get(cwBdVouchtempB.getOrimoney());
            if (obj instanceof BigDecimal) {
                orimoney = (BigDecimal) obj;
            } else if (obj instanceof String) {
                orimoney = new BigDecimal((String) obj);
            } else
                orimoney = null;
        } else {
            // 公式存在计算走三方接口
            orimoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getOrimoney(), map);
        }
        // 本币金额  默认与原币金额相同
        BigDecimal basemoney = orimoney;
        if (!cwBdVouchtempB.getOrimoney().equals(cwBdVouchtempB.getBasemoney())) {
            // 公式不同时重新计算
            if (map.containsKey(cwBdVouchtempB.getBasemoney())) {
                Object obj = map.get(cwBdVouchtempB.getBasemoney());
                if (obj instanceof BigDecimal) {
                    basemoney = (BigDecimal) obj;
                } else if (obj instanceof String) {
                    basemoney = new BigDecimal((String) obj);
                } else
                    basemoney = null;
            } else {
                // 公式存在计算走三方接口
                basemoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getBasemoney(), map);
            }
        }
        if (orimoney == null || basemoney == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    FinanceStatusCode.EXP_CALCULATION_FAILURE.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.EXP_CALCULATION_FAILURE));
        }
        // 凭证分录信息实体
        CwGlDetailWeb cwGlDetailWeb = new CwGlDetailWeb();
        String abstracts = getAbstracts(thirdBusiBenlistInfo, cwBdScenario, cwBdVouchtempB.getAbstracts());
        cwGlDetailWeb.setAbstracts(abstracts);
        cwGlDetailWeb.setPkAccsubj(cwBdAccsubj.getPkAccsubj());
        cwGlDetailWeb.setSubjcode(cwBdAccsubj.getSubjcode());// 必传
        cwGlDetailWeb.setSubjname(cwBdAccsubj.getSubjname());
        cwGlDetailWeb.setPkCurrtype(cwBdVouchtempB.getPkCurrtype());
        if (FinanceDictConsts.Cwjdfx.JIE.equals(cwBdVouchtempB.getDirection())) {
            cwGlDetailWeb.setDebitamount(orimoney);
            cwGlDetailWeb.setLocaldebitamount(basemoney);
            cwGlDetailWeb.setCreditamount(new BigDecimal("0"));
            cwGlDetailWeb.setLocalcreditamount(new BigDecimal("0"));
        } else {
            cwGlDetailWeb.setDebitamount(new BigDecimal("0"));
            cwGlDetailWeb.setLocaldebitamount(new BigDecimal("0"));
            cwGlDetailWeb.setCreditamount(orimoney);
            cwGlDetailWeb.setLocalcreditamount(basemoney);
        }
        List<CwGlFreevalue> cwGlFreevalueList = new ArrayList<CwGlFreevalue>();
        // 查询凭证模板分录辅助配置
        List<CwBdVouchtempF> cwBdVouchtempFList = CwBdVouchtempFMapper.selectByPkVouchtempB(cwBdVouchtempB.getPkVouchtempB());
        for (CwBdVouchtempF cwBdVouchtempF : cwBdVouchtempFList) {
            CwGlFreevalue cwGlFreevalue = new CwGlFreevalue();
            cwGlFreevalue.setChecktype(cwBdVouchtempF.getPkAccass());
            // 获得辅助值
            String methodValue = null;
            try {
                // 辅助值(可能有判断条件)
                String assvalue = getAssValue(cwBdVouchtempF, thirdBusiBenlistInfo);

                if (StringUtils.isBlank(assvalue)) {// 如果为空则跳过
                    continue;
                }
                // 通用情况
                methodValue = (String) FinancePublicUtil.getMethodValue(thirdBusiBenlistInfo, assvalue);
            } catch (Exception e) {
                log.error("获取辅助值失败>>>>>>>>>", e);
            }
            if (StringUtils.isBlank(methodValue)) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, cwBdVouchtempF.getAssvalue() + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
            }
            cwGlFreevalue.setCheckvalue(methodValue);
            cwGlFreevalueList.add(cwGlFreevalue);
        }
        cwGlDetailWeb.setCwGlFreevalueList(cwGlFreevalueList);// 辅助信息
        // TODO 如果分录金额为0就过滤掉(先按这种模式来)
        if (cwGlDetailWeb.getLocalcreditamount().compareTo(BigDecimal.ZERO) != 0 || cwGlDetailWeb.getLocaldebitamount().compareTo(BigDecimal.ZERO) != 0) {
            cwGlDetailList.add(cwGlDetailWeb);
        }
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }


    /**
     * 功能描述：自动审核记账
     *
     * @param addCwGlVoucher
     * @param cwGlVoucherWeb
     * @param userId
     * @param map
     * @param tradeCode
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author dml
     * @date 2019年7月4日 上午11:56:39
     * @修改日志：
     */
    private RestfulResponse<Object, CurrencyMeta> automaticAuditAndSign(RestfulResponse<Object, CurrencyMeta> addCwGlVoucher,
                                                                        CwGlVoucherWeb cwGlVoucherWeb, String userId, Map<String, Object> map) {
        CwBdParametric audit = cwBdParametricMapper.searchCwBdParametricByCode("1001");
        // 查询是否自动记账
        CwBdParametric sign = cwBdParametricMapper.searchCwBdParametricByCode("1002");
        if (audit != null && audit.getParametricValue().equals(FinanceDictConsts.Syzt.EFFECTIVE)) {
            // 查询自动审核记账人员配置
            List<CwBdAccounting> selectCwBdAccountingByLikes = cwBdAccountingMapper.selectCwBdAccountingByLikes(userId);
            if (selectCwBdAccountingByLikes.isEmpty()) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.GET_ACCOUNTING_ERROR.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.GET_ACCOUNTING_ERROR));
            }
            // 凭证信息实体
            CwGlVoucher cwGlVoucher = new CwGlVoucher();
            cwGlVoucherWeb.setPkVoucher((String) addCwGlVoucher.getData());
            cwGlVoucherWeb.setPkAudit(selectCwBdAccountingByLikes.get(0).getPkAudit());
            cwGlVoucherWeb.setPkSign(selectCwBdAccountingByLikes.get(0).getPkSign());
            BeanUtils.copyProperties(cwGlVoucherWeb, cwGlVoucher);
            // 自动审批
            List<CwGlVoucher> cwGlVouchers = new ArrayList<>();
            cwGlVouchers.add(cwGlVoucher);
            // 調用审批服务
            RestfulResponse<Object, CurrencyMeta> updateCwGlVoucherByPkForBatch = cwGlVoucherService.updateCwGlVoucherByPkForBatch(cwGlVouchers);
            if (SysConstants.CODE.FAIL == updateCwGlVoucherByPkForBatch.getCode().intValue()) {
                return updateCwGlVoucherByPkForBatch;
            }
            //审核成功记录
            map.put("isaudit", FinanceDictConsts.SF.yes);
            cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表
            if (sign != null && FinanceDictConsts.Syzt.EFFECTIVE.equals(sign.getParametricValue())) {
                // 自动记账
                RestfulResponse<Object, CurrencyMeta> updateCwGlVoucherForBookingBatch = cwGlVoucherService.updateCwGlVoucherForBookingBatch(cwGlVouchers);
                if (SysConstants.CODE.FAIL == updateCwGlVoucherForBookingBatch.getCode().intValue()) {
                    return updateCwGlVoucherForBookingBatch;
                }
                map.put("issign", FinanceDictConsts.SF.yes);
                //记账成功记录
                cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表

            }
        }
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * 功能描述  生成凭证-受益权级别更改特殊情况
     *
     * @param fundsFlowInfoList  流水list
     * @param voucherRequestInfo 记账实体
     * @param cwBdScenario       交易场景实体
     * @param serialPkList       记录流水主键list
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author huangpeng
     * @date 2019年8月13日 下午8:52:23
     * 修改日志:
     */
    private RestfulResponse<Object, CurrencyMeta> createVoucherForSpecialThree(List<FundsFlowInfo> fundsFlowInfoList,
                                                                               VoucherRequestInfo voucherRequestInfo, CwBdScenario cwBdScenario, List<String> serialPkList) {
        FundsFlowInfo fundsFlowInfo = fundsFlowInfoList.get(0);
        // 业务数据非空校验
        if (fundsFlowInfo.chackData() != null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, fundsFlowInfo.chackData() + SysStatusCode.SERVER_CHECK_ERROR.message(),
                    MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_CHECK_ERROR));
        }
        // 查询账套信息
        CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByXtzxmbh(fundsFlowInfo.getXtzxmbh());
        if (cwBdGlorgbook == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    FinanceStatusCode.GLORGBOOK_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.GLORGBOOK_MISMATCH));
        }
        String userId = (String) getFieldValue(fundsFlowInfo, cwBdScenario, "lrry");
        // 获取会计期间
        String periodNow = FinanceDateUtil.getPeriod(voucherRequestInfo.getPreparedate());
        String period = getPeriod(cwBdGlorgbook.getPkGlorgbook(), periodNow);

        //CwBdSubjscheme cwBdSubjscheme = cwBdSubjschemeMapper.selectByEnablestate();//查询正在启动的科目版本
        String pkSubjscheme = cwBdGlorgbook.getPkSubjscheme();
        // 新增制单实体类
        CwGlVoucherWeb cwGlVoucherWeb = new CwGlVoucherWeb();
        cwGlVoucherWeb.setFqmjbh(fundsFlowInfo.getFqcpbh());
        cwGlVoucherWeb.setOccDate(fundsFlowInfo.getJysj() == null ? fundsFlowInfo.getTransTime() : fundsFlowInfo.getJysj());
        cwGlVoucherWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
        cwGlVoucherWeb.setPkVoucherty(FinanceDictConsts.Cwpzlx.JIZPZ);
        cwGlVoucherWeb.setVouchertype(FinanceDictConsts.Cwpzzt.YZD);
        cwGlVoucherWeb.setPkPrepared(userId);
        cwGlVoucherWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        cwGlVoucherWeb.setPeriod(period);
        cwGlVoucherWeb.setPkSystem("01");
        cwGlVoucherWeb.setAbstracts(cwBdScenario.getJycjmc());
        cwGlVoucherWeb.setTradecode(voucherRequestInfo.getTradeCode());

        // 用于存放凭证分录信息
        List<CwGlDetailWeb> cwGlDetailList = new ArrayList<CwGlDetailWeb>();
        for (FundsFlowInfo fundsFlowInfo1 : fundsFlowInfoList) {
            String subjcode = getCwBdVouchtemp(fundsFlowInfo1, cwBdScenario);//暂时设置凭证模板主键为科目
            if (StringUtils.isBlank(subjcode)) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
            }
            CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectCwBdAccsubjBySubcode(subjcode, pkSubjscheme);
            CwGlDetailWeb cwGlDetailWeb = new CwGlDetailWeb();
            cwGlDetailWeb.setPkAccsubj(cwBdAccsubj.getPkAccsubj());
            cwGlDetailWeb.setSubjcode(subjcode);// 必传
            cwGlDetailWeb.setSubjname(cwBdAccsubj.getSubjname());
            cwGlDetailWeb.setPkCurrtype(fundsFlowInfo1.getBzdm());
            cwGlDetailWeb.setAbstracts(cwBdScenario.getJycjmc());

            if ("2".equals(fundsFlowInfo1.getZjfx())) {//金额设置 转出则设置借方金额
                cwGlDetailWeb.setDebitamount(fundsFlowInfo1.getJyfe());//暂时设置Jyfe为借贷方金额
                cwGlDetailWeb.setLocaldebitamount(fundsFlowInfo1.getJyfe());
                cwGlDetailWeb.setCreditamount(new BigDecimal("0"));
                cwGlDetailWeb.setLocalcreditamount(new BigDecimal("0"));
            } else if ("1".equals(fundsFlowInfo1.getZjfx())) {// 转入则设置贷方金额
                cwGlDetailWeb.setDebitamount(new BigDecimal("0"));
                cwGlDetailWeb.setLocaldebitamount(new BigDecimal("0"));
                cwGlDetailWeb.setCreditamount(fundsFlowInfo1.getJyfe());
                cwGlDetailWeb.setLocalcreditamount(fundsFlowInfo1.getJyfe());
            }
            List<CwGlFreevalue> cwGlFreevalueList = new ArrayList<CwGlFreevalue>();
            List<CwBdAccassitem> searchPkAccassitemList = cwBdAccassitemMapper.searchPkAccassitemList(pkSubjscheme, cwBdAccsubj.getPkAccsubj());// 查询科目的辅助项详情
            String reString = setCwBdAccassitemList(fundsFlowInfo1, searchPkAccassitemList, cwGlFreevalueList);//设置4002相关的辅助项
            if (reString != null) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, reString + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
            }
            cwGlDetailWeb.setCwGlFreevalueList(cwGlFreevalueList);// 辅助信息
            // TODO 如果分录金额为0就过滤掉(先按这种模式来)
            if (cwGlDetailWeb.getLocalcreditamount().compareTo(BigDecimal.ZERO) != 0 || cwGlDetailWeb.getLocaldebitamount().compareTo(BigDecimal.ZERO) != 0) {
                cwGlDetailList.add(cwGlDetailWeb);
            }
        }
        if (cwGlDetailList.size() == 0) {//分录上的金额借贷都为零
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL));
        }
        // 计算借方合计和贷方合计
        BigDecimal totaldebit = new BigDecimal("0"), totalcredit = new BigDecimal("0");
        for (CwGlDetailWeb cwGlDetailWeb : cwGlDetailList) {
            totaldebit = totaldebit.add(cwGlDetailWeb.getLocaldebitamount());
            totalcredit = totalcredit.add(cwGlDetailWeb.getLocalcreditamount());
            // 给分录设置账套主键和制单日期
            cwGlDetailWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
            cwGlDetailWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        }
        // 借贷平衡判断
        if (totaldebit.compareTo(totalcredit) != 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.LOAN_NOT_BALANCE.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.LOAN_NOT_BALANCE));
        }
        cwGlVoucherWeb.setTotaldebit(totaldebit);// 借方合计
        cwGlVoucherWeb.setTotalcredit(totalcredit);// 贷方合计
        cwGlVoucherWeb.setCwGlDetailList(cwGlDetailList);

        // 获取当前最大凭证号
        // CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoMapper.selectGetMaxNo(cwBdGlorgbook.getPkGlorgbook(),period);

        CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoService.getVoucherMaxNo(cwBdGlorgbook.getPkGlorgbook(), period);
        if (cwGlVouchermaxno == null || StringUtils.isBlank(cwGlVouchermaxno.getMaxno())) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    FinanceStatusCode.MAXNO_INFO_NOTFOUND.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.MAXNO_INFO_NOTFOUND));
        }
        // 凭证号
        String voucherno = Integer.valueOf(cwGlVouchermaxno.getMaxno()) + 1 + "";
        cwGlVoucherWeb.setVoucherno(voucherno);

        RestfulResponse<Object, CurrencyMeta> addCwGlVoucher = cwGlVoucherService.addCwGlVoucher(cwGlVoucherWeb);

        // 新增凭证单据明细对应关系等
        if (SysConstants.CODE.SUCCESS == addCwGlVoucher.getCode().intValue()) {
            String batchNo = voucherRequestInfo.getBatchNo();
            String tradeCode = voucherRequestInfo.getTradeCode();

            Map<String, Object> map = new HashMap<String, Object>();//流水记录表
            String pkVoucher = (String) addCwGlVoucher.getData();
            map.put("pkVoucher", pkVoucher);
            map.put("signType", FinanceDictConsts.STATE.success);
            map.put("list", serialPkList);
            map.put("failReason", "");
            map.put("batchNo", batchNo);
            map.put("tradecode", tradeCode);
            map.put("updateTime", new Date());
            cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表


            CwBdRelation cwBdRelation = new CwBdRelation();
            cwBdRelation.setPkRelation(SnowflakeIdWorker.getInstance().nextIdString());
            //cwBdRelation.setPkSrcbilltype(cwBdVouchtemp.getPkBilltype());
            cwBdRelation.setPkSrcbillpk(fundsFlowInfo.getId());
            cwBdRelation.setPkVoucher((String) addCwGlVoucher.getData());
            cwBdRelation.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
            cwBdRelation.setCreateUser(userId);
            cwBdRelation.setCreateTime(new Date());
            // 新增凭证单据明细对应关系
            cwBdRelationMapper.insert(cwBdRelation);
            try {
                automaticAuditAndSign(addCwGlVoucher, cwGlVoucherWeb, userId, map);
            } catch (Exception e) {
                log.error("自动审核记账异常>>>>>>>>>", e);
            }
        }
        return addCwGlVoucher;
    }
    
    /**
     * 功能描述：生成凭证-受益权转让（模板）特殊情况
     * @param fundsFlowInfoList 流水list
     * @param voucherRequestInfo 记账实体
     * @param cwBdScenario 交易场景实体
     * @param serialPkList 记录流水主键list
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author leiyu
     * @date 2020年7月6日 上午9:55:55
     */
    @Transactional(rollbackFor = Exception.class)
    private RestfulResponse<Object, CurrencyMeta> createVoucherForSpecialEight(List<FundsFlowInfo> fundsFlowInfoList,
            VoucherRequestInfo voucherRequestInfo, CwBdScenario cwBdScenario, List<String> serialPkList) {
		FundsFlowInfo fundsFlowInfo = fundsFlowInfoList.get(0);
		// 业务数据非空校验
		if (fundsFlowInfo.chackData() != null) {
			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
					fundsFlowInfo.chackData() + SysStatusCode.SERVER_CHECK_ERROR.message(),
					MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_CHECK_ERROR));
		}
		// 查询账套信息
		CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByXtzxmbh(fundsFlowInfo.getXtzxmbh());
		if (cwBdGlorgbook == null) {
			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
					FinanceStatusCode.GLORGBOOK_MISMATCH.message(),
					MetaDataUtil.getMeta(tracer, FinanceStatusCode.GLORGBOOK_MISMATCH));
		}
		String userId = (String) getFieldValue(fundsFlowInfo, cwBdScenario, "lrry");
		// 获取会计期间
		String periodNow = FinanceDateUtil.getPeriod(voucherRequestInfo.getPreparedate());
		String period = getPeriod(cwBdGlorgbook.getPkGlorgbook(), periodNow);

		// String pkSubjscheme = cwBdGlorgbook.getPkSubjscheme();
		List<CwGlVoucherWeb> cwGlVoucherWebList = new ArrayList<CwGlVoucherWeb>();
		
		// 获取凭证模板编号
        String pkVouchtemp = getCwBdVouchtemp(fundsFlowInfo, cwBdScenario);
        if (StringUtils.isNoneBlank(pkVouchtemp)) {
            // 可能会一条流水生成多条凭证
            String[] pkArray = pkVouchtemp.split(",");
            RestfulResponse<Object, CurrencyMeta> result = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                    MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
            int flag = 0;
            for (String pk : pkArray) {
            	// 新增制单实体类
        		CwGlVoucherWeb cwGlVoucherWeb = new CwGlVoucherWeb();
        		cwGlVoucherWeb.setFqmjbh(fundsFlowInfo.getFqcpbh());
        		cwGlVoucherWeb.setOccDate(fundsFlowInfo.getJysj() == null ? fundsFlowInfo.getTransTime() : fundsFlowInfo.getJysj());
        		cwGlVoucherWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
        		cwGlVoucherWeb.setVouchertype(FinanceDictConsts.Cwpzzt.YZD);
        		cwGlVoucherWeb.setPkPrepared(userId);
        		cwGlVoucherWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        		cwGlVoucherWeb.setPeriod(period);
        		cwGlVoucherWeb.setTradecode(voucherRequestInfo.getTradeCode());
        		
            	// 根据凭证模板编号查询对应凭证模板信息
                CwBdVouchtemp cwBdVouchtemp = cwBdVouchtempMapper.selectByCode(pk);
                if (cwBdVouchtemp == null) {
                    return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                            MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
                }
                cwGlVoucherWeb.setPkVoucher(null);
                cwGlVoucherWeb.setPkVoucherty(cwBdVouchtemp.getPkVouchertype());
                cwGlVoucherWeb.setPkSystem(cwBdVouchtemp.getSrcsystem());
                String abstracts = getAbstracts(fundsFlowInfo, cwBdScenario, cwBdVouchtemp.getAbstracts());
                cwGlVoucherWeb.setAbstracts(abstracts);// 摘要
                
                // 用于存放凭证分录信息
        		List<CwGlDetailWeb> cwGlDetailList = new ArrayList<CwGlDetailWeb>();        		        		
        		// 查询凭证模板分录配置表
        		for (FundsFlowInfo fundsFlowInfo1 : fundsFlowInfoList) {
        			// 查询凭证分录
        	        List<CwBdVouchtempB> cwBdVouchtempBList = cwBdVouchtempBMapper.selectByPkVouchtemp(cwBdVouchtemp.getPkVouchtemp());
        	        for (CwBdVouchtempB cwBdVouchtempB : cwBdVouchtempBList) {
        	            // 循环分录组装分录信息
        	            RestfulResponse<Object, CurrencyMeta> setCwGlDetailWeb = null;
        	            // 正常情况
        	            setCwGlDetailWeb = setCwGlDetailWebForEight(cwGlVoucherWeb, cwGlDetailList, fundsFlowInfo1, fundsFlowInfoList, cwBdScenario, cwBdVouchtempB);
        	            if (SysConstants.CODE.FAIL == setCwGlDetailWeb.getCode().intValue()) {
        	                return setCwGlDetailWeb;
        	            }
        	        }
        	        
        		}
        		if (cwGlDetailList.size() == 0) {// 分录上的金额借贷都为零
        			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
        					FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message(),
        					MetaDataUtil.getMeta(tracer, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL));
        		}
        		// 计算借方合计和贷方合计
        		BigDecimal totaldebit = new BigDecimal("0"), totalcredit = new BigDecimal("0");
        		for (CwGlDetailWeb cwGlDetailWeb : cwGlDetailList) {
        			totaldebit = totaldebit.add(cwGlDetailWeb.getLocaldebitamount());
        			totalcredit = totalcredit.add(cwGlDetailWeb.getLocalcreditamount());
        			// 给分录设置账套主键和制单日期
        			cwGlDetailWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
        			cwGlDetailWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        		}
        		// 借贷平衡判断
        		if (totaldebit.compareTo(totalcredit) != 0) {
        			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
        					FinanceStatusCode.LOAN_NOT_BALANCE.message(),
        					MetaDataUtil.getMeta(tracer, FinanceStatusCode.LOAN_NOT_BALANCE));
        		}
        		cwGlVoucherWeb.setTotaldebit(totaldebit);// 借方合计
        		cwGlVoucherWeb.setTotalcredit(totalcredit);// 贷方合计
        		cwGlVoucherWeb.setCwGlDetailList(cwGlDetailList);
        		// 获取当前最大凭证号
        		CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoMapper.selectGetMaxNo(cwBdGlorgbook.getPkGlorgbook(),period);

        		// CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoService.getVoucherMaxNo(cwBdGlorgbook.getPkGlorgbook(),period);
        		if (cwGlVouchermaxno == null || StringUtils.isBlank(cwGlVouchermaxno.getMaxno())) {
        			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
        					FinanceStatusCode.MAXNO_INFO_NOTFOUND.message(),
        					MetaDataUtil.getMeta(tracer, FinanceStatusCode.MAXNO_INFO_NOTFOUND));
        		}
        		// 凭证号
        		String voucherno = Integer.valueOf(cwGlVouchermaxno.getMaxno()) + 1 + "";
        		++flag;
        		if(flag > 1) {
        			voucherno = Integer.valueOf(voucherno) + 1 + "";
        		}
        		cwGlVoucherWeb.setVoucherno(voucherno);  
        		cwGlVoucherWebList.add(cwGlVoucherWeb);
            }
            
            RestfulResponse<Object, CurrencyMeta> addCwGlVoucher = cwGlVoucherServiceImpl.addCwGlVoucherList(cwGlVoucherWebList);
    		
    		
    		// 新增凭证单据明细对应关系等
    		if (SysConstants.CODE.SUCCESS == addCwGlVoucher.getCode().intValue()) {
    			String batchNo = voucherRequestInfo.getBatchNo();
    			String tradeCode = voucherRequestInfo.getTradeCode();

    			Map<String, Object> map = new HashMap<String, Object>();// 流水记录表
    			
    			map.put("pkVoucher", (String) addCwGlVoucher.getData());
    			map.put("signType", FinanceDictConsts.STATE.success);
    			map.put("list", serialPkList);
    			map.put("failReason", "");
    			map.put("batchNo", batchNo);
    			map.put("tradecode", tradeCode);
    			map.put("updateTime", new Date());
    			cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);// 更新流水号记录表

    			String[] pkVoucher = ((String) addCwGlVoucher.getData()).split(",");
    			int i = 0;
    	        for (String pk : pkVoucher) {
    				CwBdRelation cwBdRelation = new CwBdRelation();
        			cwBdRelation.setPkRelation(SnowflakeIdWorker.getInstance().nextIdString());
        			//cwBdRelation.setPkSrcbilltype(cwBdVouchtemp.getPkBilltype());
        			cwBdRelation.setPkSrcbillpk(fundsFlowInfo.getId());
        			cwBdRelation.setPkVoucher(pk);
        			cwBdRelation.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
        			cwBdRelation.setCreateUser(userId);
        			cwBdRelation.setCreateTime(new Date());
        			RestfulResponse<Object, CurrencyMeta> addCwGlVoucherZD =  new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, pk);
        			// 新增凭证单据明细对应关系
        			cwBdRelationMapper.insert(cwBdRelation);
        			try {
        				automaticAuditAndSign(addCwGlVoucherZD, cwGlVoucherWebList.get(i), userId, map);
        			} catch (Exception e) {
        				log.error("自动审核记账异常>>>>>>>>>", e);
        			}
        			i++;
    			}
    			
    		}
    		   		
            result = addCwGlVoucher;
            return result;
        } else {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
        }
		
	}
    
    /**
     * 功能描述：受益权转让（模板）-设置分录及其辅助项
     * @param cwGlVoucherWeb
     * @param cwGlDetailList
     * @param fundsFlowInfo
     * @param fundsFlowInfoList
     * @param cwBdScenario
     * @param cwBdVouchtempB
     * @return
     * @author leiyu
     * @date 2020年7月6日 上午11:20:39
     */
    private RestfulResponse<Object, CurrencyMeta> setCwGlDetailWebForEight(CwGlVoucherWeb cwGlVoucherWeb, List<CwGlDetailWeb> cwGlDetailList, FundsFlowInfo fundsFlowInfo,
                List<FundsFlowInfo> fundsFlowInfoList, CwBdScenario cwBdScenario, CwBdVouchtempB cwBdVouchtempB) {
    	// 查询对应科目详情
		CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectByPrimaryKey(cwBdVouchtempB.getPkAccsubj());
		// 获取表达式参数
		Map<String, Object> map = getParmMap(cwGlVoucherWeb, cwGlDetailList, fundsFlowInfo,
				fundsFlowInfoList, cwBdScenario, cwBdVouchtempB, cwBdAccsubj.getSubjcode());
		// 原币金额
		BigDecimal orimoney;
		// 如果公式直接在map存在 即公式为单个字段
		if (map.containsKey(cwBdVouchtempB.getOrimoney())) {
			Object obj = map.get(cwBdVouchtempB.getOrimoney());
			if (obj instanceof BigDecimal) {
				orimoney = (BigDecimal) obj;
			} else if (obj instanceof String) {
				orimoney = new BigDecimal((String) obj);
			} else
				orimoney = null;
		} else {
			// 公式存在计算走三方接口
			orimoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getOrimoney(), map);
		}
		// 本币金额  默认与原币金额相同
		BigDecimal basemoney = orimoney;
		if (!cwBdVouchtempB.getOrimoney().equals(cwBdVouchtempB.getBasemoney())) {
			// 公式不同时重新计算
			if (map.containsKey(cwBdVouchtempB.getBasemoney())) {
				Object obj = map.get(cwBdVouchtempB.getBasemoney());
				if (obj instanceof BigDecimal) {
					basemoney = (BigDecimal) obj;
				} else if (obj instanceof String) {
					basemoney = new BigDecimal((String) obj);
				} else
					basemoney = null;
			} else {
				// 公式存在计算走三方接口
				basemoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getBasemoney(), map);
			}
		}
		if (orimoney == null || basemoney == null) {
			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
					FinanceStatusCode.EXP_CALCULATION_FAILURE.message(),
					MetaDataUtil.getMeta(tracer, FinanceStatusCode.EXP_CALCULATION_FAILURE));
		}
		// 凭证分录信息实体
		CwGlDetailWeb cwGlDetailWeb = new CwGlDetailWeb();
		String abstracts = getAbstracts(fundsFlowInfo, cwBdScenario, cwBdVouchtempB.getAbstracts());
		cwGlDetailWeb.setAbstracts(abstracts);
		cwGlDetailWeb.setPkAccsubj(cwBdAccsubj.getPkAccsubj());
		cwGlDetailWeb.setSubjcode(cwBdAccsubj.getSubjcode());// 必传
		cwGlDetailWeb.setSubjname(cwBdAccsubj.getSubjname());
		cwGlDetailWeb.setPkCurrtype(cwBdVouchtempB.getPkCurrtype());
		if ("2".equals(fundsFlowInfo.getZjfx())) {// 金额设置 转出则设置借方金额
			cwGlDetailWeb.setDebitamount(orimoney);
			cwGlDetailWeb.setLocaldebitamount(basemoney);
			cwGlDetailWeb.setCreditamount(new BigDecimal("0"));
			cwGlDetailWeb.setLocalcreditamount(new BigDecimal("0"));
		} 
		if ("1".equals(fundsFlowInfo.getZjfx())) {// 金额设置 转入则设置贷方金额
			cwGlDetailWeb.setDebitamount(new BigDecimal("0"));
			cwGlDetailWeb.setLocaldebitamount(new BigDecimal("0"));
			cwGlDetailWeb.setCreditamount(orimoney);
			cwGlDetailWeb.setLocalcreditamount(basemoney);
		}
		List<CwGlFreevalue> cwGlFreevalueList = new ArrayList<CwGlFreevalue>();
		// 查询凭证模板分录辅助配置
		List<CwBdVouchtempF> cwBdVouchtempFList = CwBdVouchtempFMapper
				.selectByPkVouchtempB(cwBdVouchtempB.getPkVouchtempB());
		for (CwBdVouchtempF cwBdVouchtempF : cwBdVouchtempFList) {
			CwGlFreevalue cwGlFreevalue = new CwGlFreevalue();
			cwGlFreevalue.setChecktype(cwBdVouchtempF.getPkAccass());
			// 获得辅助值
			String methodValue = null;
			try {
				// 辅助值(可能有判断条件)
				String assvalue = getAssValue(cwBdVouchtempF, fundsFlowInfo);

				if (StringUtils.isBlank(assvalue)) {// 如果为空则跳过
					continue;
				}
				// 通用情况
				methodValue = (String) FinancePublicUtil.getMethodValue(fundsFlowInfo, assvalue);
			} catch (Exception e) {
				log.error("获取辅助值失败>>>>>>>>>", e);
			}
			if (StringUtils.isBlank(methodValue)) {
				return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
						cwBdVouchtempF.getAssvalue() + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
						MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
			}
			cwGlFreevalue.setCheckvalue(methodValue);
			cwGlFreevalueList.add(cwGlFreevalue);
		}
		cwGlDetailWeb.setCwGlFreevalueList(cwGlFreevalueList);// 辅助信息
		// 如果分录金额为0就过滤掉(先按这种模式来)
		if (cwGlDetailWeb.getLocalcreditamount().compareTo(BigDecimal.ZERO) != 0
				|| cwGlDetailWeb.getLocaldebitamount().compareTo(BigDecimal.ZERO) != 0) {
			cwGlDetailList.add(cwGlDetailWeb);
		}
		return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS,
				SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
	}    

    /**
     * 功能描述   财产权信托资产入账-非正常记账模式
     *
     * @param fundsFlowInfoList          流水信息
     * @param asDetailContractAssetsList 合同信托
     * @param voucherRequestInfo         记账实体
     * @param serialPkList               记录流水主键list
     * @param cwBdScenario               交易场景实体
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author huangpeng
     * @date 2019年8月13日 下午8:51:08
     * 修改日志:
     */
    private RestfulResponse<Object, CurrencyMeta> createVoucherForSpecialSix(List<FundsFlowInfo> fundsFlowInfoList,
                                                                             List<AsDetailContractAssets> asDetailContractAssetsList, VoucherRequestInfo voucherRequestInfo, List<String> serialPkList,
                                                                             CwBdScenario cwBdScenario) {
        FundsFlowInfo fundsFlowInfo = fundsFlowInfoList.get(0);
        // 业务数据非空校验
        if (fundsFlowInfo.chackData() != null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, fundsFlowInfo.chackData() + SysStatusCode.SERVER_CHECK_ERROR.message(),
                    MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_CHECK_ERROR));
        }
        if (asDetailContractAssetsList.size() == 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, "资产数据获取失败",
                    "资产数据获取失败");
        }
        // 查询账套信息
        CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByXtzxmbh(fundsFlowInfo.getXtzxmbh());
        if (cwBdGlorgbook == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    FinanceStatusCode.GLORGBOOK_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.GLORGBOOK_MISMATCH));
        }
        String pkSubjscheme = cwBdGlorgbook.getPkSubjscheme();
        String userId = (String) getFieldValue(fundsFlowInfo, cwBdScenario, "lrry");
        // 获取会计期间
        String periodNow = FinanceDateUtil.getPeriod(voucherRequestInfo.getPreparedate());
        String period = getPeriod(cwBdGlorgbook.getPkGlorgbook(), periodNow);

        // 新增制单实体类
        CwGlVoucherWeb cwGlVoucherWeb = new CwGlVoucherWeb();
        cwGlVoucherWeb.setFqmjbh(fundsFlowInfo.getFqcpbh());
        cwGlVoucherWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
        cwGlVoucherWeb.setPkVoucherty(FinanceDictConsts.Cwpzlx.JIZPZ);
        cwGlVoucherWeb.setPkSystem("01");
        cwGlVoucherWeb.setOccDate(fundsFlowInfo.getJysj() == null ? fundsFlowInfo.getTransTime() : fundsFlowInfo.getJysj());
        cwGlVoucherWeb.setVouchertype(FinanceDictConsts.Cwpzzt.YZD);
        cwGlVoucherWeb.setPkPrepared(userId);
        cwGlVoucherWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        cwGlVoucherWeb.setPeriod(period);
        cwGlVoucherWeb.setAbstracts(cwBdScenario.getJycjmc());// 摘要
        cwGlVoucherWeb.setTradecode(voucherRequestInfo.getTradeCode());
        // 用于存放凭证分录信息
        List<CwGlDetailWeb> cwGlDetailList = new ArrayList<CwGlDetailWeb>();
        //组装流水List
        for (FundsFlowInfo fundsFlowInfo1 : fundsFlowInfoList) {
            CwGlDetailWeb cwGlDetailWeb = new CwGlDetailWeb();
            String subjcode = cwBdScenariorelationMapper.selectForSpecialSix("CCLB", null, voucherRequestInfo.getTradeCode());//获取科目代码
            if (StringUtils.isBlank(subjcode)) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
            }
            CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectCwBdAccsubjBySubcode(subjcode, pkSubjscheme);//查询科目
            cwGlDetailWeb.setAbstracts(cwBdScenario.getJycjmc());
            cwGlDetailWeb.setPkAccsubj(cwBdAccsubj.getPkAccsubj());
            cwGlDetailWeb.setSubjcode(subjcode);// 必传
            cwGlDetailWeb.setSubjname(cwBdAccsubj.getSubjname());
            cwGlDetailWeb.setPkCurrtype(fundsFlowInfo1.getBzdm());
            cwGlDetailWeb.setDebitamount(new BigDecimal("0"));
            cwGlDetailWeb.setLocaldebitamount(new BigDecimal("0"));

            if ("CJ3003".equals(voucherRequestInfo.getTradeCode()) || "CJ3006".equals(voucherRequestInfo.getTradeCode())) {

                cwGlDetailWeb.setCreditamount(fundsFlowInfo1.getJyfxjje());
                cwGlDetailWeb.setLocalcreditamount(fundsFlowInfo1.getJyfxjje());
            } else {
                cwGlDetailWeb.setCreditamount(fundsFlowInfo1.getJyje());
                cwGlDetailWeb.setLocalcreditamount(fundsFlowInfo1.getJyje());
            }

            //凭证模板辅助项获取
            List<CwGlFreevalue> cwGlFreevalueList = new ArrayList<CwGlFreevalue>();
            List<CwBdAccassitem> searchPkAccassitemList = cwBdAccassitemMapper.searchPkAccassitemList(pkSubjscheme, cwBdAccsubj.getPkAccsubj());
            String reString = setCwBdAccassitemList(fundsFlowInfo1, searchPkAccassitemList, cwGlFreevalueList);
            if (reString != null) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, reString + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
            }
            cwGlDetailWeb.setCwGlFreevalueList(cwGlFreevalueList);// 辅助信息
            // TODO 如果分录金额为0就过滤掉(先按这种模式来)
            if (cwGlDetailWeb.getLocalcreditamount().compareTo(BigDecimal.ZERO) != 0 || cwGlDetailWeb.getLocaldebitamount().compareTo(BigDecimal.ZERO) != 0) {
                cwGlDetailList.add(cwGlDetailWeb);
            }
        }
        //组装合同集合list
        for (AsDetailContractAssets asDetailContractAssets : asDetailContractAssetsList) {
            CwGlDetailWeb cwGlDetailWeb = new CwGlDetailWeb();
            String subjcode = cwBdScenariorelationMapper.selectForSpecialSix("CCLB", asDetailContractAssets.getCclb(), voucherRequestInfo.getTradeCode());//获取科目代码
            if (StringUtils.isBlank(subjcode)) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
            }
            CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectCwBdAccsubjBySubcode(subjcode, pkSubjscheme);//查询科目
            //组装合同分录
            cwGlDetailWeb.setAbstracts(cwBdScenario.getJycjmc());
            cwGlDetailWeb.setPkAccsubj(cwBdAccsubj.getPkAccsubj());
            cwGlDetailWeb.setSubjcode(subjcode);// 必传
            cwGlDetailWeb.setSubjname(cwBdAccsubj.getSubjname());
            cwGlDetailWeb.setPkCurrtype(fundsFlowInfo.getBzdm());
            cwGlDetailWeb.setDebitamount(asDetailContractAssets.getZcrzjz());//借方金额
            cwGlDetailWeb.setLocaldebitamount(asDetailContractAssets.getZcrzjz());
            cwGlDetailWeb.setCreditamount(new BigDecimal("0"));
            cwGlDetailWeb.setLocalcreditamount(new BigDecimal("0"));
            //凭证模板辅助项获取
            List<CwGlFreevalue> cwGlFreevalueList = new ArrayList<CwGlFreevalue>();
            List<CwBdAccassitem> searchPkAccassitemList = cwBdAccassitemMapper.searchPkAccassitemList(pkSubjscheme, cwBdAccsubj.getPkAccsubj());
            for (CwBdAccassitem cwBdAccassitem : searchPkAccassitemList) {
                CwGlFreevalue cwGlFreevalue = new CwGlFreevalue();
                cwGlFreevalue.setChecktype(cwBdAccassitem.getPkAccassitem());
                if ("FZ0005".equals(cwBdAccassitem.getCode())) {//投资合同
                    if (StringUtils.isBlank(asDetailContractAssets.getYyhtbh())) {
                        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, cwBdAccassitem.getName() + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
                                MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
                    } else {
                        cwGlFreevalue.setCheckvalue(asDetailContractAssets.getYyhtbh());
                    }
                } else if ("FZ0010".equals(cwBdAccassitem.getCode())) {//投资合同借据
                    if (StringUtils.isBlank(asDetailContractAssets.getJjbh())) {
                        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, cwBdAccassitem.getName() + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
                                MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
                    } else {
                        cwGlFreevalue.setCheckvalue(asDetailContractAssets.getJjbh());
                    }
                } else {
                    continue;
                }
                cwGlFreevalueList.add(cwGlFreevalue);
            }
            cwGlDetailWeb.setCwGlFreevalueList(cwGlFreevalueList);// 辅助信息
            // TODO 如果分录金额为0就过滤掉(先按这种模式来)
            if (cwGlDetailWeb.getLocalcreditamount().compareTo(BigDecimal.ZERO) != 0 || cwGlDetailWeb.getLocaldebitamount().compareTo(BigDecimal.ZERO) != 0) {
                cwGlDetailList.add(cwGlDetailWeb);
            }
        }
        if (cwGlDetailList.size() == 0) {//分录上的金额借贷都为零
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL));
        }
        // 计算借方合计和贷方合计
        BigDecimal totaldebit = new BigDecimal("0"), totalcredit = new BigDecimal("0");
        for (CwGlDetailWeb cwGlDetailWeb : cwGlDetailList) {
            totaldebit = totaldebit.add(cwGlDetailWeb.getLocaldebitamount());
            totalcredit = totalcredit.add(cwGlDetailWeb.getLocalcreditamount());
            // 给分录设置账套主键和制单日期
            cwGlDetailWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
            cwGlDetailWeb.setPreparedate(voucherRequestInfo.getPreparedate());
        }
        // 借贷平衡判断
        if (totaldebit.compareTo(totalcredit) != 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.LOAN_NOT_BALANCE.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.LOAN_NOT_BALANCE));
        }
        cwGlVoucherWeb.setTotaldebit(totaldebit);// 借方合计
        cwGlVoucherWeb.setTotalcredit(totalcredit);// 贷方合计
        cwGlVoucherWeb.setCwGlDetailList(cwGlDetailList);
        // 设置业务发生日期
        cwGlVoucherWeb.setOccDate(fundsFlowInfo.getJysj() == null ? fundsFlowInfo.getTransTime() : fundsFlowInfo.getJysj());

        // 获取当前最大凭证号
        // CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoMapper.selectGetMaxNo(cwBdGlorgbook.getPkGlorgbook(),period);

        CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoService.getVoucherMaxNo(cwBdGlorgbook.getPkGlorgbook(), period);

        if (cwGlVouchermaxno == null || StringUtils.isBlank(cwGlVouchermaxno.getMaxno())) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    FinanceStatusCode.MAXNO_INFO_NOTFOUND.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.MAXNO_INFO_NOTFOUND));
        }
        // 凭证号
        String voucherno = Integer.valueOf(cwGlVouchermaxno.getMaxno()) + 1 + "";
        cwGlVoucherWeb.setVoucherno(voucherno);

        // 调用新增凭证服务
        RestfulResponse<Object, CurrencyMeta> addCwGlVoucher = cwGlVoucherService.addCwGlVoucher(cwGlVoucherWeb);
        // 新增凭证单据明细对应关系等
        if (SysConstants.CODE.SUCCESS == addCwGlVoucher.getCode().intValue()) {

            String batchNo = voucherRequestInfo.getBatchNo();
            String tradeCode = voucherRequestInfo.getTradeCode();

            Map<String, Object> map = new HashMap<String, Object>();//流水记录表
            String pkVoucher = (String) addCwGlVoucher.getData();
            map.put("pkVoucher", pkVoucher);
            map.put("list", serialPkList);
            map.put("failReason", "");
            map.put("batchNo", batchNo);
            map.put("tradecode", tradeCode);
            map.put("updateTime", new Date());
            map.put("signType", FinanceDictConsts.STATE.success);
            cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表

            CwBdRelation cwBdRelation = new CwBdRelation();
            cwBdRelation.setPkRelation(SnowflakeIdWorker.getInstance().nextIdString());
//                  cwBdRelation.setPkSrcbilltype(cwBdVouchtemp.getPkBilltype());
            cwBdRelation.setPkSrcbillpk(fundsFlowInfo.getId());
            cwBdRelation.setPkVoucher((String) addCwGlVoucher.getData());
            cwBdRelation.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
            cwBdRelation.setCreateUser(userId);
            cwBdRelation.setCreateTime(new Date());
            // 新增凭证单据明细对应关系
            cwBdRelationMapper.insert(cwBdRelation);
            try {
                automaticAuditAndSign(addCwGlVoucher, cwGlVoucherWeb, userId, map);
            } catch (Exception e) {
                log.error("自动审核记账异常>>>>>>>>>", e);
            }
        }
        return addCwGlVoucher;

    }

    private String setCwBdAccassitemList(FundsFlowInfo fundsFlowInfo, List<CwBdAccassitem> searchPkAccassitemList, List<CwGlFreevalue> cwGlFreevalueList) {
        for (CwBdAccassitem cwBdAccassitem : searchPkAccassitemList) {
            CwGlFreevalue cwGlFreevalue = new CwGlFreevalue();
            cwGlFreevalue.setChecktype(cwBdAccassitem.getPkAccassitem());
            //TODO:辅助项需要确认
            if ("FZ0002".equals(cwBdAccassitem.getCode())) {//受益人编号
                if (StringUtils.isBlank(fundsFlowInfo.getSyrbh())) {
                    return cwBdAccassitem.getName();
                } else {
                    cwGlFreevalue.setCheckvalue(fundsFlowInfo.getSyrbh());
                }
            } else if ("FZ0001".equals(cwBdAccassitem.getCode())) {//委托人编号
                if (StringUtils.isBlank(fundsFlowInfo.getWtrbh())) {
                    return cwBdAccassitem.getName();
                } else {
                    cwGlFreevalue.setCheckvalue(fundsFlowInfo.getWtrbh());
                }
            } else if ("FZ0003".equals(cwBdAccassitem.getCode())) {//委托端合同
                if (StringUtils.isBlank(fundsFlowInfo.getHtid())) {
                    return cwBdAccassitem.getName();
                } else {
                    cwGlFreevalue.setCheckvalue(fundsFlowInfo.getHtid());
                }
            } else if ("FZ0008".equals(cwBdAccassitem.getCode())) {//受益分级
                if (StringUtils.isBlank(fundsFlowInfo.getSyqfj())) {
                    return cwBdAccassitem.getName();
                } else {
                    cwGlFreevalue.setCheckvalue(fundsFlowInfo.getSyqfj());
                }
            } else if ("FZ0011".equals(cwBdAccassitem.getCode())) {//项目分期
                if (StringUtils.isBlank(fundsFlowInfo.getFqcpbh())) {
                    return cwBdAccassitem.getName();
                } else {
                    cwGlFreevalue.setCheckvalue(fundsFlowInfo.getFqcpbh());
                }
            } else if ("FZ0012".equals(cwBdAccassitem.getCode())) {//受益凭据
                if (StringUtils.isBlank(fundsFlowInfo.getSypjbh())) {
                    return cwBdAccassitem.getName();
                } else {
                    cwGlFreevalue.setCheckvalue(fundsFlowInfo.getSypjbh());
                }
            } else {
                continue;
            }
            cwGlFreevalueList.add(cwGlFreevalue);
        }
        return null;
    }
//  /**
//   * 功能描述：获取受益权辅助值
//   * @param thirdBusiBenlistInfoList
//   * @param assvalue
//   * @return String
//   * @author dml
//   * @throws Exception 
//   * @date 2019年7月3日 下午2:42:48
//   * @修改日志：
//   */
//  private String getSyqzrAssValue(List<FundsFlowInfo> thirdBusiBenlistInfoList , String assvalue) throws Exception {
//      String[] split = StringUtils.split(assvalue,":");
//      String[] split2 = StringUtils.split(split[0],"?");
//      String substr = StringUtils.substring(split2[1], StringUtils.indexOf(split2[1], "=")+1);
//      for (FundsFlowInfo fundsFlowInfo : thirdBusiBenlistInfoList) {
//          String methodValue = (String) FinancePublicUtil.getMethodValue(fundsFlowInfo,split2[0]);
//          if (methodValue.equals(substr)) {
//              return (String) FinancePublicUtil.getMethodValue(fundsFlowInfo,split[1]);
//          }
//      }
//      return null;
//  }

    /**
     * 功能描述：获取辅助值
     *
     * @param cwBdVouchtempF
     * @param thirdBusiBenlistInfo
     * @return String
     * @throws Exception
     * @author dml
     * @date 2019年7月1日 下午7:59:50
     * @修改日志：
     */
    private String getAssValue(CwBdVouchtempF cwBdVouchtempF, FundsFlowInfo thirdBusiBenlistInfo) throws Exception {
        if (StringUtils.isBlank(cwBdVouchtempF.getAssvalue())) {
            return null;
        }
        String assValue = cwBdVouchtempF.getAssvalue();
        // 下边的符号都是英文的
        if (StringUtils.isNotBlank(assValue) && StringUtils.contains(assValue, "|")) {
            String[] split = StringUtils.split(assValue, "|");
            String methodValue = (String) FinancePublicUtil.getMethodValue(thirdBusiBenlistInfo, split[0]);
            String substr = StringUtils.substring(split[1], StringUtils.indexOf(split[1], "=") + 1);
            String prefix = StringUtils.substring(split[1], 0, StringUtils.indexOf(split[1], "=") + 1);
            if ("=".equals(prefix)) {
                if (methodValue.equals(substr)) {
                    return split[2];
                }
            } else if ("!=".equals(prefix) || "！=".equals(prefix)) {
                if (!methodValue.equals(substr)) {
                    return split[2];
                }
            }
        } else {
            return assValue;
        }
        return null;
    }

    /**
     * 功能描述：如果已记账则获取下一个会计期间
     *
     * @param pkGlorgbook
     * @param period
     * @return String
     * @author dml
     * @date 2019年6月13日 下午3:38:47
     * @修改日志：
     */
    private String getPeriod(String pkGlorgbook, String period) {
// 不在这做判断       
//      long count = cwGlSettleMapper.countIsSettle(pkGlorgbook, period);
//      String res = period;
//      if (count > 0) {
//          String lastMonth = FinanceDateUtil.getLastMonth(period, "yyyy-MM", 1);
//          res = getPeriod(pkGlorgbook, lastMonth);
//      }
        return period;
    }

    /**
     * 功能描述：查询字段值
     *
     * @param thirdBusiBenlistInfo
     * @param cwBdScenario
     * @param name
     * @return Object
     * @author dml
     * @date 2019年8月2日 下午4:38:51
     * @修改日志：
     */
    private Object getFieldValue(FundsFlowInfo thirdBusiBenlistInfo, CwBdScenario cwBdScenario, String name) {
        return FinancePublicUtil.getMethodValueNoexc(thirdBusiBenlistInfo, cacheMap.get(cwBdScenario.getFlowType() + name));
    }

    /**
     * 功能描述：根据不同场景获取交易模板
     *
     * @param thirdBusiBenlistInfo
     * @return String
     * @author dml
     * @date 2019年6月26日 上午10:43:22
     * @修改日志：
     */
    private String getCwBdVouchtemp(FundsFlowInfo thirdBusiBenlistInfo, CwBdScenario cwBdScenario) {
        try {
            if (cwBdScenario == null) {
                return null;
            }
            Field[] fields = cwBdScenario.getClass().getDeclaredFields();
            // 存放表字段名和实体类字段名
            Map<String, String> resultMap = new HashMap<String, String>();
            for (Field field : fields) {
                // 没有注解的跳过
                if (!field.isAnnotationPresent(TableColumnName.class)) {
                    continue;
                }
                field.setAccessible(true); // 设置私有属性是可以访问
                String beanName = field.getName();
                Object object = field.get(cwBdScenario);
                TableColumnName annotation = field.getAnnotation(TableColumnName.class);
                String columnname = annotation.columnname();
                if (object instanceof String) {
                    String value = (String) object;
                    if (FinanceDictConsts.Syzt.EFFECTIVE.equals(value)) {
                        resultMap.put(beanName, columnname);
                    }
                }
            }
            // 拼接动态sql
            StringBuilder sb = new StringBuilder(" SELECT  PK_VOUCHTEMP  FROM   CW_BD_SCENARIORELATION  WHERE  "
                    + "USE_STATE = '1' AND JYM = '" + cwBdScenario.getJym() + "'    ");
            Set<Entry<String, String>> entrySet = resultMap.entrySet();
            for (Entry<String, String> entry : entrySet) {
                sb.append(" AND ");
                sb.append(entry.getValue());
                // 获取对应字段的值
                String flowField = cacheMap.get(cwBdScenario.getFlowType() + entry.getKey());
                String methodValue = (String) FinancePublicUtil.getMethodValue(thirdBusiBenlistInfo, flowField);
                if (StringUtils.isBlank(methodValue)) {
                    sb.append("  IS NULL");
                } else {
                    sb.append("  =  ");
                    sb.append("'" + methodValue + "'");
                }
            }
            String pkCwBdVouchtemp = cwBdScenariorelationMapper.selectCwBdVouchtemp(sb.toString());
            return pkCwBdVouchtemp;
        } catch (Exception e) {
            log.error("获取凭证模板编号异常>>>>>>>>>>>>>>", e);
        }
        return null;
    }

    /**
     * 功能描述：获取全部字段对应关系加入map
     *
     * @param flowType
     * @param scenarioField
     * @return String
     * @author dml
     * @date 2019年7月29日 下午2:54:03
     * @修改日志：
     */
    private void initScenariofield() {
        List<CwBdScenariofield> selectAllData = cwBdScenariofieldMapper.selectAllData();
        try {
            commitLock.lock();
            cacheMap.clear();
            for (CwBdScenariofield cwBdScenariofield : selectAllData) {
                cacheMap.put(cwBdScenariofield.getFlowType() + cwBdScenariofield.getScenarioField(), cwBdScenariofield.getFlowField());
            }
        } finally {
            commitLock.unlock();
        }

    }

    /**
     * 功能描述：查询流水信息
     *
     * @param voucherRequestInfo
     * @param cwBdScenario
     * @return List<FundsFlowInfo>
     * @author dml
     * @date 2019年7月30日 上午11:04:02
     * @修改日志：
     */
    private List<FundsFlowInfo> getFlowInfo(VoucherRequestInfo voucherRequestInfo, CwBdScenario cwBdScenario) {
        List<FundsFlowInfo> res = new ArrayList<FundsFlowInfo>();
        try {
            if ("2".equals(voucherRequestInfo.getParamType())) {// 传流水号过来
                if (voucherRequestInfo.getFlowNo() == null || voucherRequestInfo.getFlowNo().isEmpty()) {
                    return res;
                }
                StringBuilder sb = new StringBuilder("select a.* from " + FinanceDictConsts.FLOWTYPE.map.get(cwBdScenario.getFlowType())
                        + "  a  where ");
                sb.append("a." + cacheMap.get(cwBdScenario.getFlowType() + "flowNo"));
                sb.append("  in (");
                voucherRequestInfo.getFlowNo().forEach(x -> {
                    sb.append("'" + x + "',");
                });
                sb.deleteCharAt(sb.length() - 1);
                sb.append(") ");
                sb.append("  and  a." + cacheMap.get(cwBdScenario.getFlowType() + "useState"));
                sb.append(" = '1'");
                res = financeForThirdMapper.selectFundsFlowInfo(sb.toString());
            } else if ("3".equals(voucherRequestInfo.getParamType())) {// 传流水详情
                res = voucherRequestInfo.getFundsFlowInfoList();
            } else {// 传批次号
                if ("4".equals(cwBdScenario.getFlowType())) {
                    String sql = " select  a.HKSQBH, a.HKPCH, a.HKSX, a.HKYHBH, a.HKYHZH, a.HKYT, a.HKRQ, a.HKJE, a.HKFS, a.SKDW, a.SKYHZH, a.SKYHBH, a.SHYHZHBH, a.SFHWSKH,"
                            + " a.KHHSF, a.KHHCS, a.LRRY, a.LRSJ, a.ZHXGRY, a.ZHXGSJ, a.SKLX, a.SEQ_NO, a.ISCOMPLETE, a.SELECTED, a.ZLZXZT, a.YYZXZT, a.MSHKZT, a.CWPCH, "
                            + "a.EJHKLX, a.PZCLZT, a.WYCLZT,b.cwrybh  as hskjbh,b.xtzxmbh as xtzxmbh  from ACC_TRANSFER_PROCESS a left join acc_transfer_info "
                            + " b on  a.HKSQBH=b.HKSQBH   where a.cwpch= '" + voucherRequestInfo.getBatchNo() + "'";
                    res = financeForThirdMapper.selectFundsFlowInfo(sql);
                } else {
                    StringBuilder sb = new StringBuilder("select a.* from " + FinanceDictConsts.FLOWTYPE.map.get(cwBdScenario.getFlowType())
                            + " a  where ");
                    sb.append("a." + cacheMap.get(cwBdScenario.getFlowType() + "batchNo"));
                    sb.append("  =  '" + voucherRequestInfo.getBatchNo() + "'");
                    sb.append("  and  a." + cacheMap.get(cwBdScenario.getFlowType() + "useState"));
                    sb.append(" = '1'");
                    res = financeForThirdMapper.selectFundsFlowInfo(sb.toString());
                }
            }
        } catch (Exception e) {
            log.error("查询流水异常>>>>>>>>>>", e);
        }
        return res;
    }

    /**
     * 功能描述：获取损益平准金比例
     * 【（4002、4003、4103、4104）已实现利得+收入-费用】：【（4002、4003、4103、4104）已实现利得+收入-费用】+【（4002、4003、4103、4104）未实现利得+6101科目余额】
     * 如果为0则返回1
     *
     * @param pkGlorgbook
     * @param period
     * @return BigDecimal
     * @author dml
     * @date 2019年7月22日 下午2:29:09
     * @修改日志：
     */
    private BigDecimal getProportion(String pkGlorgbook, String period) {
        BigDecimal proportion = cwGlBalanceMapper.selectProportion(pkGlorgbook, period);
        BigDecimal defaultval = new BigDecimal("0");
        if (defaultval.compareTo(proportion) == 0) {
            return new BigDecimal("1");
        }
        return proportion;
    }
    /*
     * (非 Javadoc)
     * <p>Title: updateBusiBenlistInfoForBatch</p>
     * <p>Description: 冲抹账</p>
     * @param thirdBusiBenlistInfo
     * @return
     * @see com.dhcc.finance.main.service.FinanceForThirdService#updateBusiBenlistInfoForBatch(com.dhcc.finance.main.model.ThirdBusiBenlistInfo)
     * @author huangpeng
     * @date 2019年6月14日 下午3:28:57
     * @修改日志：
     */

    @Transactional(rollbackFor = Exception.class)
    RestfulResponse<Object, CurrencyMeta> createVoucherForSpecialSeven(
            List<FundsFlowInfo> fundsFlowInfoList, VoucherRequestInfo voucherRequestInfo, CwBdScenario cwBdScenario, List<String> serialPkList) {
        String flowType = cwBdScenario.getFlowType();
        String YPCH = (String) FinancePublicUtil.getMethodValueNoexc(fundsFlowInfoList.get(0), cacheMap.get(flowType + "ypch"));//原批次号
        String userId = (String) getFieldValue(fundsFlowInfoList.get(0), cwBdScenario, "lrry");
//      List<String> oldSerialList = new ArrayList<String>();//原流水号
//      for (FundsFlowInfo fundsFlowInfo : fundsFlowInfoList) {
//          String oldSerial=(String)FinancePublicUtil.getMethodValueNoexc(fundsFlowInfo, cacheMap.get(flowType+"yjylsbh"));//原流水号
//          oldSerialList.add(oldSerial);
//      }
        List<String> voucherList = cwBdRecordSerialMapper.searchVoucherByBatchno(YPCH);
        if (voucherList.size() == 0) {//原批次下不存在凭证信息，不需要进行反交易
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    FinanceStatusCode.BATCHNO_ISNOTEXIST_DEAL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.BATCHNO_ISNOTEXIST_DEAL));
        }
        List<String> pkList = new ArrayList<String>();
        for (String pkVoucher : voucherList) {
            if (StringUtils.contains(pkVoucher, ",")) {
                String[] split = pkVoucher.split(",");
                for (String string : split) {
                    pkList.add(string);
                }
            } else {
                pkList.add(pkVoucher);
            }

        }
        String newPkVoucher = "";//用于记录新的凭证号
        for (String pkVoucher : pkList) {
            CwGlVoucherWeb cwGlVoucherWeb = cwGlVoucherMapper.selectOrderMakingDetil(pkVoucher, FinanceDictConsts.Syzt.EFFECTIVE);//查询凭证详情
            if (cwGlVoucherWeb == null) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                        FinanceStatusCode.VOUCHER_IS_DELETE.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_IS_DELETE));
            }
            String pkGlorgbook = cwGlVoucherWeb.getPkGlorgbook();//账套
            String period = cwGlVoucherWeb.getPeriod();//会计期间
            CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByPrimaryKey(pkGlorgbook);
            //long count = cwGlSettleMapper.countIsSettle(pkGlorgbook, period);// 查询该账套期间下已结账数目
            if (!period.equals(cwBdGlorgbook.getPkCurrperiod())) {// 不在当前期间
                String newPeiod = FinanceDateUtil.getPeriod(voucherRequestInfo.getPreparedate());//得到新的会计期间

                CwGlVoucherWeb cwGlVoucherWeb1 = new CwGlVoucherWeb();//生成冲凭证准备
                BeanUtils.copyProperties(cwGlVoucherWeb, cwGlVoucherWeb1);
                if (newPeiod.equals(cwBdGlorgbook.getPkCurrperiod())) {//若与当前期间相同
                    cwGlVoucherWeb1.setPreparedate(voucherRequestInfo.getPreparedate());
                    cwGlVoucherWeb1.setPeriod(newPeiod);
                } else {//若与当前期间不同，则去当前期间最后一天
                    Date monthLastDayDate = FinanceDateUtil.getMonthLastDayDate(cwBdGlorgbook.getPkCurrperiod());
                    cwGlVoucherWeb1.setPreparedate(monthLastDayDate);
                    cwGlVoucherWeb1.setPeriod(cwBdGlorgbook.getPkCurrperiod());
                }
                cwGlVoucherWeb1.setPkVoucher(null);
                cwGlVoucherWeb1.setTradecode(voucherRequestInfo.getTradeCode());
                cwGlVoucherWeb1.setVouchertype(FinanceDictConsts.Cwpzzt.YZD);
                cwGlVoucherWeb1.setPkPrepared(userId);
                cwGlVoucherWeb1.setOccDate((Date) getFieldValue(fundsFlowInfoList.get(0), cwBdScenario, "jysj"));
                cwGlVoucherWeb1.setAbstracts("冲" + cwGlVoucherWeb.getAbstracts());
                cwGlVoucherWeb1.setTotalcredit(cwGlVoucherWeb.getTotaldebit().negate());
                cwGlVoucherWeb1.setTotaldebit(cwGlVoucherWeb.getTotaldebit().negate());
                cwGlVoucherWeb1.setIsaudit("0");
                cwGlVoucherWeb1.setIssign("0");
                cwGlVoucherWeb1.setPkAudit(null);
                cwGlVoucherWeb1.setPkSign(null);
                cwGlVoucherWeb1.setAuditdate(null);
                cwGlVoucherWeb1.setSigndate(null);
                cwGlVoucherWeb1.setUpdateTime(null);
                cwGlVoucherWeb1.setUpdateUser(null);
                List<CwGlDetailWeb> cwGlDetailList = cwGlVoucherWeb.getCwGlDetailList();//分录信息
                for (CwGlDetailWeb cwGlDetailWeb : cwGlDetailList) {
                    cwGlDetailWeb.setPkDetail(null);
                    cwGlDetailWeb.setUpdateTime(null);
                    cwGlDetailWeb.setUpdateUser(null);
                    cwGlDetailWeb.setPreparedate(cwGlVoucherWeb1.getPreparedate());
                    cwGlDetailWeb.setAbstracts("冲" + cwGlDetailWeb.getAbstracts());
                    cwGlDetailWeb.setDebitamount(
                            cwGlDetailWeb.getDebitamount() == null ? null : cwGlDetailWeb.getDebitamount().negate());
                    cwGlDetailWeb.setCreditamount(
                            cwGlDetailWeb.getCreditamount() == null ? null : cwGlDetailWeb.getCreditamount().negate());
                    cwGlDetailWeb.setLocalcreditamount(cwGlDetailWeb.getLocalcreditamount() == null ? null
                            : cwGlDetailWeb.getLocalcreditamount().negate());
                    cwGlDetailWeb.setLocaldebitamount(cwGlDetailWeb.getLocaldebitamount() == null ? null
                            : cwGlDetailWeb.getLocaldebitamount().negate());
                    List<CwGlFreevalue> cwGlFreevalueList = cwGlDetailWeb.getCwGlFreevalueList();
                    List<CwGlFreevalue> arrayList = new ArrayList<CwGlFreevalue>();
                    if (StringUtils.isNotBlank(cwGlDetailWeb.getAssid())) {
                        for (CwGlFreevalue cwGlFreevalue : cwGlFreevalueList) {
                            CwGlFreevalue cwGlFreevalue2 = new CwGlFreevalue();
                            cwGlFreevalue2.setChecktype(cwGlFreevalue.getChecktype());
                            cwGlFreevalue2.setCheckvalue(cwGlFreevalue.getCheckvalue());
                            arrayList.add(cwGlFreevalue2);
                        }
                        cwGlDetailWeb.setCwGlFreevalueList(arrayList);
                    } else {
                        cwGlDetailWeb.setCwGlFreevalueList(null);
                    }

                }

                // CwGlVouchermaxno voucherNo = cwGlVouchermaxnoMapper.selectGetMaxNo(pkGlorgbook, newPeiod);//得到最大凭证号

                CwGlVouchermaxno voucherNo = cwGlVouchermaxnoService.getVoucherMaxNo(pkGlorgbook, newPeiod);

                if (voucherNo == null || StringUtils.isBlank(voucherNo.getMaxno())) {
                    return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.MAXNO_INFO_NOTFOUND.message(),
                            MetaDataUtil.getMeta(tracer, FinanceStatusCode.MAXNO_INFO_NOTFOUND));
                }
                cwGlVoucherWeb1.setVoucherno(Integer.valueOf(voucherNo.getMaxno()) + 1 + "");

                RestfulResponse<Object, CurrencyMeta> addCwGlVoucher = cwGlVoucherService.addCwGlVoucher(cwGlVoucherWeb1);// 生成凭证
                if (SysConstants.CODE.SUCCESS == addCwGlVoucher.getCode().intValue()) {

                    String batchNo = voucherRequestInfo.getBatchNo();
                    String tradeCode = voucherRequestInfo.getTradeCode();

                    Map<String, Object> map = new HashMap<String, Object>();//流水记录表
                    String newVoucher = (String) addCwGlVoucher.getData();
                    if (StringUtils.isNoneBlank(newPkVoucher)) {
                        map.put("pkVoucher", newPkVoucher + "," + newVoucher);
                        newPkVoucher = newPkVoucher + "," + newVoucher;
                    } else {
                        map.put("pkVoucher", newVoucher);
                        newPkVoucher = newVoucher;
                    }
                    map.put("list", serialPkList);
                    map.put("failReason", "");
                    map.put("batchNo", batchNo);
                    map.put("tradecode", tradeCode);
                    map.put("updateTime", new Date());
                    map.put("signType", FinanceDictConsts.STATE.success);
                    cwBdRecordSerialMapper.updateRecordByserialNoForBatch(map);//更新流水号记录表
                    try {
                        automaticAuditAndSign(addCwGlVoucher, cwGlVoucherWeb1, userId, map);
                    } catch (Exception e) {
                        log.error("自动审核记账异常>>>>>>>>>", e);
                    }
                } else {
                    return addCwGlVoucher;
                }
            } else {//在当前会计期间
                List<CwGlVoucher> delVoucher = new ArrayList<CwGlVoucher>();
                CwGlVoucher cwGlVoucher = new CwGlVoucher();
                BeanUtils.copyProperties(cwGlVoucherWeb, cwGlVoucher);
                cwGlVoucher.setUpdateUser(userId);
                delVoucher.add(cwGlVoucher);
                if (FinanceDictConsts.Syzt.EFFECTIVE.equals(cwGlVoucher.getIssign())) {
                    RestfulResponse<Object, CurrencyMeta> res0 = cwGlVoucherService.updateCwGlVoucherForReverseBooking(delVoucher);// 反记账
                    if (SysConstants.CODE.FAIL == res0.getCode().intValue()) {
                        return res0;
                    }
                }
                if (FinanceDictConsts.Syzt.EFFECTIVE.equals(cwGlVoucher.getIsaudit())) {
                    RestfulResponse<Object, CurrencyMeta> res = cwGlVoucherService.updateCwGlVoucherForReverse(delVoucher);// 反审核
                    if (SysConstants.CODE.FAIL == res.getCode().intValue()) {
                        return res;
                    }
                }
                cwGlVoucherService.deleteCwGlVoucherByPk(pkVoucher);// 逻辑删除凭证
            }
        }

        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS,
                SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc) Title: createGlorgbookInfo Description:生成账套信息
     * @param thirdPrdFqmjInfo
     * @return
     * @see
     * com.dhcc.finance.main.service.FinanceForThirdService#createGlorgbookInfo(com.
     * dhcc.finance.main.model.ThirdPrdFqmjInfo)
     * @author dml
     * @date 2019年6月4日 下午3:15:20
     * @修改日志：
     */
//  @Transactional(rollbackFor = Exception.class)
    @Override
    public RestfulResponse<Object, CurrencyMeta> createGlorgbookInfo(ThirdPmProjectChild thirdPmProjectChild) {

        SysUserInfo sysUserInfo = CacheDataUtil.getCacheBean(stringRedisTemplate,
                SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);

        CwBdRecordGlorgbook cwBdRecordGlorgbook = new CwBdRecordGlorgbook();
        //生成建账记录信息实体类
        String pkGlorgbookRecordId = SnowflakeIdWorker.getInstance().nextIdString();
        cwBdRecordGlorgbook.setId(pkGlorgbookRecordId);
        if (sysUserInfo != null) {
            cwBdRecordGlorgbook.setInitiateUse(sysUserInfo.getUserId());
            cwBdRecordGlorgbook.setCreateUser(sysUserInfo.getUserId());
        }
        cwBdRecordGlorgbook.setInitiateTime(new Date());
        cwBdRecordGlorgbook.setProjectCode(thirdPmProjectChild.getXtzxmbh());
        cwBdRecordGlorgbook.setProjectName(thirdPmProjectChild.getXtzxmqc());
        cwBdRecordGlorgbook.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
        cwBdRecordGlorgbook.setCreateTime(new Date());
        cwBdRecordGlorgbook.setBuildType(FinanceDictConsts.Syzt.INVALID);
        // 向建账记录信息表插入建账记录信息
        cwBdRecordGlorgbookMapper.insertSelective(cwBdRecordGlorgbook);

        // 生成账套信息
        RestfulResponse<Object, CurrencyMeta> createGlorgbookInfos = null;
        try {
            createGlorgbookInfos = financeForThirdSupplyService.createGlorgbookInfo(thirdPmProjectChild);
        } catch (Exception e) {
            createGlorgbookInfos = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    SysStatusCode.SERVER_UNKNOWN_ERROR.message(),
                    MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_UNKNOWN_ERROR));
            log.error("生成账套异常>>>>>>>>>>>>>>>>>>>>", e);
        }
        if (SysConstants.CODE.SUCCESS == createGlorgbookInfos.getCode().intValue()) {
            // 自动建账成功，修改记录表状态
            if (sysUserInfo != null) {
                cwBdRecordGlorgbook.setUpdateTime(new Date());
                cwBdRecordGlorgbook.setUpdateUser(sysUserInfo.getUserId());
            }
            cwBdRecordGlorgbook.setBuildType(FinanceDictConsts.Syzt.EFFECTIVE);
            cwBdRecordGlorgbookMapper.updateByPrimaryKeySelective(cwBdRecordGlorgbook);
        } else {
            cwBdRecordGlorgbook.setFailReason(createGlorgbookInfos.getMsg());  // 添加失败的原因
            cwBdRecordGlorgbookMapper.updateByPrimaryKeySelective(cwBdRecordGlorgbook);
            if (FinanceStatusCode.GLORGBOOK_EXISTING.message().equals(createGlorgbookInfos.getMsg())) {
                createGlorgbookInfos.setCode(SysConstants.CODE.SUCCESS);
            }
        }
        return createGlorgbookInfos;
    }

    /*
     * (非 Javadoc)
     * <p>Title: searchCwBdGlorgbookForNewAdd</p>
     * <p>Description:  查询新增账套接口 </p>
     * @return
     * @see com.dhcc.finance.main.service.FinanceForThirdService#searchCwBdGlorgbookForNewAdd()
     * @author huangpeng
     * @date 2019年7月13日 上午11:22:48
     * @修改日志：
     */
    @Override
    public RestfulResponse<List<CwBdGlorgbook>, CurrencyMeta> searchCwBdGlorgbookForNewAdd() {
        List<CwBdGlorgbook> list = cwBdGlorgbookMapper.searchCwBdGlorgbookForNewAdd();
        return new RestfulResponse<List<CwBdGlorgbook>, CurrencyMeta>(SysConstants.CODE.SUCCESS,
                SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, list,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc)
     * <p>Title: searchCwGlVoucherTodayAdd</p>
     * <p>Description:查询今日新增凭证接口</p>
     * @return
     * @see com.dhcc.finance.main.service.FinanceForThirdService#searchCwGlVoucherTodayAdd()
     * @author huangpeng
     * @date 2019年7月13日 上午11:58:13
     * @修改日志：
     */
    @Override
    public RestfulResponse<List<CwGlVoucherAndName>, CurrencyMeta> searchCwGlVoucherTodayAdd() {
        List<CwGlVoucherAndName> list = cwGlVoucherMapper.searchCwGlVoucherTodayAdd();
        return new RestfulResponse<List<CwGlVoucherAndName>, CurrencyMeta>(SysConstants.CODE.SUCCESS,
                SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, list,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc)
     * Title: searchPaidInTrust
     * Description:按照单一集合财产权查询实收信托
     * @return
     * @see com.dhcc.finance.main.service.FinanceForThirdService#searchPaidInTrust()
     * @author dml
     * @date 2019年11月17日 下午4:54:54
     * @修改日志：
     */
    @Override
    public RestfulResponse<List<XmlxAndBalance>, CurrencyMeta> searchPaidInTrust() {
        List<XmlxAndBalance> searchPaidInTrust = financeForThirdMapper.searchPaidInTrust();
        return new RestfulResponse<List<XmlxAndBalance>, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                searchPaidInTrust, MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc)
     * Title: searchAssetScale
     * Description:按照单一集合财产权查询资产端规模
     * @return
     * @see com.dhcc.finance.main.service.FinanceForThirdService#searchAssetScale()
     * @author dml
     * @date 2019年11月17日 下午4:54:57
     * @修改日志：
     */
    @Override
    public RestfulResponse<List<XmlxAndBalance>, CurrencyMeta> searchAssetScale() {
        List<XmlxAndBalance> searchAssetScale = financeForThirdMapper.searchAssetScale();
        return new RestfulResponse<List<XmlxAndBalance>, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                searchAssetScale, MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc)
     * Title: createGlorgbookInfoBatch
     * Description:批量建账
     * @param thirdPmProjectChildList
     * @return
     * @see com.dhcc.finance.main.service.FinanceForThirdService#createGlorgbookInfoBatch(java.util.List)
     * @author dml
     * @date 2020年3月9日 下午2:29:02
     * @修改日志：
     */
    @Override
    public RestfulResponse<Object, CurrencyMeta> createGlorgbookInfoBatch(List<ThirdPmProjectChild> thirdPmProjectChildList) {
        if (thirdPmProjectChildList == null || thirdPmProjectChildList.size() == 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, SysStatusCode.SERVER_CHECK_ERROR.message(),
                    MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_CHECK_ERROR));
        }
        SysUserInfo sysUserInfo = CacheDataUtil.getCacheBean(stringRedisTemplate,
                SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);
        List<CwBdRecordGlorgbook> cwBdRecordGlorgbookList = new ArrayList<CwBdRecordGlorgbook>();
        for (ThirdPmProjectChild thirdPmProjectChild : thirdPmProjectChildList) {
            CwBdRecordGlorgbook cwBdRecordGlorgbook = new CwBdRecordGlorgbook();
            //生成建账记录信息实体类
            cwBdRecordGlorgbook.setId(SnowflakeIdWorker.getInstance().nextIdString());
            if (sysUserInfo != null) {
                cwBdRecordGlorgbook.setInitiateUse(sysUserInfo.getUserId());
                cwBdRecordGlorgbook.setCreateUser(sysUserInfo.getUserId());
            }
            cwBdRecordGlorgbook.setInitiateTime(new Date());
            cwBdRecordGlorgbook.setProjectCode(thirdPmProjectChild.getXtzxmbh());
            cwBdRecordGlorgbook.setProjectName(thirdPmProjectChild.getXtzxmqc());
            cwBdRecordGlorgbook.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
            cwBdRecordGlorgbook.setCreateTime(new Date());
            cwBdRecordGlorgbook.setBuildType(FinanceDictConsts.Syzt.INVALID);
            cwBdRecordGlorgbook.setXtxmbh(thirdPmProjectChild.getXtxmbh());
            cwBdRecordGlorgbookList.add(cwBdRecordGlorgbook);
        }
        int res1 = cwBdRecordGlorgbookMapper.insertDataBatch(cwBdRecordGlorgbookList);
        if (res1 < 1) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, SysStatusCode.SERVER_CHECK_ERROR.message(),
                    MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_CHECK_ERROR));
        }
        // 生成账套信息
        RestfulResponse<List<CwBdRecordGlorgbook>, CurrencyMeta> createGlorgbookInfos = null;
        try {
            createGlorgbookInfos = financeForThirdSupplyService.createGlorgbookInfoBatch(cwBdRecordGlorgbookList);
        } catch (Exception e) {
            createGlorgbookInfos = new RestfulResponse<List<CwBdRecordGlorgbook>, CurrencyMeta>(SysConstants.CODE.FAIL,
                    SysStatusCode.SERVER_UNKNOWN_ERROR.message(), null,
                    MetaDataUtil.getMeta(tracer, SysStatusCode.SERVER_UNKNOWN_ERROR));
            log.error("生成账套异常>>>>>>>>>>>>>>>>>>>>", e);
        }
        if (SysConstants.CODE.SUCCESS == createGlorgbookInfos.getCode().intValue()) {
            List<CwBdRecordGlorgbook> pass = new ArrayList<CwBdRecordGlorgbook>();// 校验通过
            List<CwBdRecordGlorgbook> noPass = new ArrayList<CwBdRecordGlorgbook>();// 校验不通过
            List<CwBdRecordGlorgbook> noPasYjz = new ArrayList<CwBdRecordGlorgbook>();// 除开已记账校验不通过的
            List<CwBdRecordGlorgbook> data = createGlorgbookInfos.getData();
            for (CwBdRecordGlorgbook cwBdRecordGlorgbook : data) {
                if (StringUtils.isBlank(cwBdRecordGlorgbook.getFailReason())) {
                    if (sysUserInfo != null) {
                        cwBdRecordGlorgbook.setUpdateUser(sysUserInfo.getUserId());
                    }
                    cwBdRecordGlorgbook.setUpdateTime(new Date());
                    cwBdRecordGlorgbook.setBuildType(FinanceDictConsts.Syzt.EFFECTIVE);
                    pass.add(cwBdRecordGlorgbook);
                } else {
                    if (sysUserInfo != null) {
                        cwBdRecordGlorgbook.setUpdateUser(sysUserInfo.getUserId());
                    }
                    cwBdRecordGlorgbook.setUpdateTime(new Date());
                    noPass.add(cwBdRecordGlorgbook);
                    if (!FinanceStatusCode.GLORGBOOK_EXISTING.message().equals(cwBdRecordGlorgbook.getFailReason())) {
                        noPasYjz.add(cwBdRecordGlorgbook);
                    }
                }
            }
            int updateDataBatch = cwBdRecordGlorgbookMapper.updateDataBatch(data);
            if (noPasYjz.size() == 0 && updateDataBatch > 0) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS,
                        SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                        MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
            }
        } else {
            for (CwBdRecordGlorgbook result : cwBdRecordGlorgbookList) {
                result.setFailReason(SysStatusCode.OPERATION_FAIL.message());
                if (sysUserInfo != null) {
                    result.setUpdateUser(sysUserInfo.getUserId());
                }
                result.setUpdateTime(new Date());
            }
        }
        cwBdRecordGlorgbookMapper.updateDataBatch(cwBdRecordGlorgbookList);
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, SysStatusCode.OPERATION_FAIL.message(),
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_FAIL));
    }

    /*public static void main(String[] args) {
        int j = 10000;
        for (int i = 0; i < 120; i++) {
            String string = "{\"xtzxmbh\":\"" + (j + i) + "\",\"xtxmbh\":\"1\",\"xtzxmqc\":\"dml测试" + i + "\"},";
            System.out.println(string);
        }

    }*/

    /**
     * 功能描述:固有代垫生成凭证接口,并对传入参数做记录
     *
     * @param fundsFlowInfoGydds
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author likai
     * @data 2020年4月15日下午3:18:46
     * 修改日志
     */
    @Override
    public RestfulResponse<Object, CurrencyMeta> createVoucherInfoGydd(String params) {
        // json格式转换成list实体类
        List<FundsFlowInfoGydd> fundsFlowInfoGydds = JSONArray.parseArray(params, FundsFlowInfoGydd.class);
        Date date = new Date();
        String batchNo = SnowflakeIdWorker.getInstance().nextIdString(); //获取批次号
        String id = SnowflakeIdWorker.getInstance().nextIdString(); //获取id
        CwNcAdvanceRequest cwNcAdvanceRequest = new CwNcAdvanceRequest();
        cwNcAdvanceRequest.setId(id);
        cwNcAdvanceRequest.setBatchNo(batchNo);
        cwNcAdvanceRequest.setCreateTime(date);
        cwNcAdvanceRequest.setCreateUser("admin");
        cwNcAdvanceRequest.setInParams(params);
        cwNcAdvanceRequest.setRemark("");
        cwNcAdvanceRequest.setUpdateTime(date);
        cwNcAdvanceRequest.setUpdateUser("admin");
        cwNcAdvanceRequest.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
        int response = cwNcAdvanceRequestMapper.insert(cwNcAdvanceRequest);
        if (response <= 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.INSERT_ADVANCE_FAIL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.INSERT_ADVANCE_FAIL));
        }
        List<CwNcAdvanceCostflow> cwNcAdvanceCostflows = new ArrayList<CwNcAdvanceCostflow>();

        for (FundsFlowInfoGydd fundsFlowInfoGydd : fundsFlowInfoGydds) {
            CwNcAdvanceCostflow cwNcAdvanceCostflow = new CwNcAdvanceCostflow();
            String flowId = SnowflakeIdWorker.getInstance().nextIdString(); //获取id
            cwNcAdvanceCostflow.setBatchNo(batchNo);
            cwNcAdvanceCostflow.setId(flowId);
            cwNcAdvanceCostflow.setCreateTime(date);
            cwNcAdvanceCostflow.setCreateUser("admin");
            cwNcAdvanceCostflow.setUpdateTime(date);
            cwNcAdvanceCostflow.setUpdateUser("admin");
            cwNcAdvanceCostflow.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
            cwNcAdvanceCostflow.setProjectId(fundsFlowInfoGydd.getXtxmbh());
            cwNcAdvanceCostflow.setSubProjectId(fundsFlowInfoGydd.getXtzxmbh());
            cwNcAdvanceCostflow.setProjectName(fundsFlowInfoGydd.getXtxmqc());
            cwNcAdvanceCostflow.setAccountNo(fundsFlowInfoGydd.getXtzxmbh());
            cwNcAdvanceCostflow.setAdvanceAmount(fundsFlowInfoGydd.getGhddkje());
            cwNcAdvanceCostflows.add(cwNcAdvanceCostflow);

        }
        int resp = cwNcAdvanceCostflowMapper.batchInsertCostflow(cwNcAdvanceCostflows);
        if (resp <= 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.INSERT_COSTFLOW_FAIL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.INSERT_COSTFLOW_FAIL));
        }
        createVoucherGydd(params, fundsFlowInfoGydds);


        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * 功能描述：固有代垫生成凭证接口
     *
     * @param params
     * @param fundsFlowInfoGydds
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author likai
     * @date 2020年5月29日 下午7:49:09
     * @修改日志：
     * suh修改：2020年7月8日 下午7:44:09    将固有代垫还款的冲销凭证，制单人设置成固定人，且使用常量设置
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public RestfulResponse<Object, CurrencyMeta> createVoucherGydd(String params, List<FundsFlowInfoGydd> fundsFlowInfoGydds) {
        // 循环固有代垫list，
        for (FundsFlowInfoGydd fundsFlowInfoGydd : fundsFlowInfoGydds) {
            BigDecimal ghddkje = fundsFlowInfoGydd.getGhddkje(); // 取该项目下的固有代垫款金额 50000
            // 根据项目编号查询该项目下的子项目编号、账套编号、代垫金额、核算会计等信息
            List<FundProjectInfoGydd> fundProjectInfoGydds =
                    financeForThirdMapper.selectAdvanceByXtxmbh(fundsFlowInfoGydd.getXtxmbh());
            if (fundProjectInfoGydds.size() <= 0) {
                CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.searchGlorgbookByXtxmbh(fundsFlowInfoGydd.getXtxmbh());
                if (cwBdGlorgbook == null) {
                    return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.GLORGBOOK_MISMATCH.message(),
                            MetaDataUtil.getMeta(tracer, FinanceStatusCode.GLORGBOOK_MISMATCH));
                }
                // 取到固有代垫模板
                String pkVouchtemp = FinanceDictConsts.MBLX.GYDD;
                Date preparedate = new Date();//制单日期暂时设置为当前日期
                //调用生成凭证方法
                FundProjectInfoGydd flowInfoGydd = new FundProjectInfoGydd();
                flowInfoGydd.setBalance(ghddkje);
                flowInfoGydd.setPkCurrperiod(cwBdGlorgbook.getPkCurrperiod());

                //设置核算会计为固定人
                flowInfoGydd.setUserId(MsConfigConsts.GYDD_PK_PREPARED);
                RestfulResponse<Object, CurrencyMeta> res = voucherInfoDetailGydd(pkVouchtemp, cwBdGlorgbook.getXtzxmbh(), preparedate, flowInfoGydd);
                if (SysConstants.CODE.FAIL == res.getCode().intValue()) {
                    throwNewException(res);
                }
            }
            for (int i = 0; i < fundProjectInfoGydds.size(); i++) {
                BigDecimal balance = null;
                if (i + 1 == fundProjectInfoGydds.size() && ghddkje.compareTo(new BigDecimal(0)) > 0) {
                    balance = ghddkje;
                } else {
                    // 生成凭证传入的金额= 如果子项目的代垫款金额小于项目的代垫款金额，则金额等于子项目的代垫款金额，否则等于项目的代垫款金额
                    balance = fundProjectInfoGydds.get(i).getBalance().compareTo(ghddkje) == -1 ? fundProjectInfoGydds.get(i).getBalance() : ghddkje;
                }
                // 判断项目的固有代垫款金额大于0
                if (ghddkje.compareTo(BigDecimal.ZERO) == 1) {
                    // 取到固有代垫模板
                    String pkVouchtemp = FinanceDictConsts.MBLX.GYDD;
                    Date preparedate = new Date();//制单日期暂时设置为当前日期
                    fundProjectInfoGydds.get(i).setBalance(balance);

                    //设置核算会计为固定人
                    fundProjectInfoGydds.get(i).setUserId(MsConfigConsts.GYDD_PK_PREPARED);

                    //调用生成凭证方法
                    RestfulResponse<Object, CurrencyMeta> res = voucherInfoDetailGydd(pkVouchtemp, fundProjectInfoGydds.get(i).getXtzxmbh(), preparedate, fundProjectInfoGydds.get(i));
                    if (SysConstants.CODE.FAIL == res.getCode().intValue()) {
                        throwNewException(res);
                    }
                }
                // 子项目生成凭证之后，项目的归还代垫款金额减去子项目的归还代垫款金额
                ghddkje = ghddkje.subtract(fundProjectInfoGydds.get(i).getBalance());
                //如果项目的归还代垫款小于0则跳出内层循环
                int t = ghddkje.compareTo(new BigDecimal(0));
                if (t <= 0) {
                    break;
                }
            }
            /*for(FundProjectInfoGydd fundProjectInfoGydd :fundProjectInfoGydds) {
                // 生成凭证传入的金额= 如果子项目的代垫款金额小于项目的代垫款金额，则金额等于子项目的代垫款金额，否则等于项目的代垫款金额
                BigDecimal balance = fundProjectInfoGydd.getBalance().compareTo(ghddkje) == -1 ? fundProjectInfoGydd.getBalance():ghddkje;
               // 判断项目的固有代垫款金额大于0
                if (ghddkje.compareTo(BigDecimal.ZERO) == 1 ) {
                    // 取到固有代垫模板
                    String pkVouchtemp = FinanceDictConsts.MBLX.GYDD ;
                    Date preparedate = new Date();//制单日期暂时设置为当前日期
                    fundProjectInfoGydd.setBalance(balance);
                    //调用生成凭证方法
                    RestfulResponse<Object, CurrencyMeta> res = voucherInfoDetailGydd(pkVouchtemp,fundProjectInfoGydd.getXtzxmbh(),preparedate,fundProjectInfoGydd);
                    if (SysConstants.CODE.FAIL == res.getCode().intValue()) {
                        throwNewException(res);
                  }
                }
                // 子项目生成凭证之后，项目的归还代垫款金额减去子项目的归还代垫款金额
                ghddkje =  ghddkje.subtract(fundProjectInfoGydd.getBalance());
                //如果项目的归还代垫款小于0则跳出内层循环
                int i = ghddkje.compareTo(new BigDecimal(0));
                if (i<=0) {
                    break;
                }
            }*/
        }
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * 功能描述:固有代垫生成凭证详情
     *
     * @param fundsFlowInfoGydds
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author likai
     * @data 2020年4月15日下午3:18:46
     * 修改日志
     */
    private RestfulResponse<Object, CurrencyMeta> voucherInfoDetailGydd(String pkVouchtemp, String xtzxmbh, Date preparedate, FundProjectInfoGydd fundProjectInfoGydd) {
        // 根据凭证模板编号查询对应凭证模板信息
        CwBdVouchtemp cwBdVouchtemp = cwBdVouchtempMapper.selectByCode(pkVouchtemp);
        if (cwBdVouchtemp == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUCHER_TEMPLATE_MISMATCH));
        }
        // 查询账套信息
        CwBdGlorgbook cwBdGlorgbook = cwBdGlorgbookMapper.selectByXtzxmbh(xtzxmbh);
        if (cwBdGlorgbook == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.GLORGBOOK_MISMATCH.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.GLORGBOOK_MISMATCH));
        }
        /*// 获取会计期间
        String periodNow = FinanceDateUtil.getPeriod(preparedate);
        // 如果已记账则获取下一个会计期间
        String period = getPeriod(cwBdGlorgbook.getPkGlorgbook(), periodNow);*/


        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
        Date date;
        try {
            date = df.parse(fundProjectInfoGydd.getPkCurrperiod());
        } catch (ParseException e) {
            e.printStackTrace();
            date = new Date();
        }

        int dateOne = FinanceDateUtil.getYearMonth(date);
        int dateTwo = FinanceDateUtil.getYearMonth(preparedate);
        Date preparedate1 = new Date();
        if (dateOne == dateTwo) {
            preparedate1 = new Date();
        } else if (dateOne < dateTwo) {
            preparedate1 = FinanceDateUtil.getMonthLastDayDate(fundProjectInfoGydd.getPkCurrperiod());
        } else {
            preparedate1 = FinanceDateUtil.getMonthFirstDay(fundProjectInfoGydd.getPkCurrperiod());
        }
        // 新增制单实体类
        // 设置 凭证信息实体参数
        CwGlVoucherWeb cwGlVoucherWeb = new CwGlVoucherWeb();
        cwGlVoucherWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
        cwGlVoucherWeb.setPkVoucherty(cwBdVouchtemp.getPkVouchertype());
        cwGlVoucherWeb.setPkSystem(cwBdVouchtemp.getSrcsystem());
        cwGlVoucherWeb.setVouchertype(FinanceDictConsts.Cwpzzt.YZD);

        cwGlVoucherWeb.setPkPrepared(fundProjectInfoGydd.getUserId()); // 制单人用录入人员取子项目的核算会计
        cwGlVoucherWeb.setPreparedate(preparedate1);
        cwGlVoucherWeb.setPeriod(fundProjectInfoGydd.getPkCurrperiod());
        String abstracts = cwBdVouchtemp.getAbstracts();
        cwGlVoucherWeb.setAbstracts(abstracts);// 摘要
        // 设置业务发生日期
        cwGlVoucherWeb.setOccDate(new Date());
        // 用于存放凭证分录信息
        List<CwGlDetailWeb> cwGlDetailList = new ArrayList<CwGlDetailWeb>();
        RestfulResponse<Object, CurrencyMeta> detailInfo = getDetailInfoGydd(cwGlDetailList, fundProjectInfoGydd, cwBdVouchtemp);
        if (SysConstants.CODE.FAIL == detailInfo.getCode().intValue()) {
            return detailInfo;
        }
        if (cwGlDetailList.size() == 0) {//分录上的金额借贷都为零
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.DETAIL_ACCOUNT_ISNULL));
        }
        // 计算借方合计和贷方合计
        BigDecimal totaldebit = new BigDecimal("0"), totalcredit = new BigDecimal("0");
        for (CwGlDetailWeb cwGlDetailWeb : cwGlDetailList) {
            totaldebit = totaldebit.add(cwGlDetailWeb.getLocaldebitamount());
            totalcredit = totalcredit.add(cwGlDetailWeb.getLocalcreditamount());
            // 给分录设置账套主键和制单日期
            cwGlDetailWeb.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
            cwGlDetailWeb.setPreparedate(preparedate1);
        }
        // 借贷平衡判断
        if (totaldebit.compareTo(totalcredit) != 0) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.LOAN_NOT_BALANCE.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.LOAN_NOT_BALANCE));
        }
        cwGlVoucherWeb.setTotaldebit(totaldebit);// 借方合计
        cwGlVoucherWeb.setTotalcredit(totalcredit);// 贷方合计
        cwGlVoucherWeb.setCwGlDetailList(cwGlDetailList);// 分录信信息

        // 获取当前最大凭证号
        // CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoMapper.selectGetMaxNo(cwBdGlorgbook.getPkGlorgbook(), fundProjectInfoGydd.getPkCurrperiod());

        CwGlVouchermaxno cwGlVouchermaxno = cwGlVouchermaxnoService.getVoucherMaxNo(cwBdGlorgbook.getPkGlorgbook(), fundProjectInfoGydd.getPkCurrperiod());

        if (cwGlVouchermaxno == null || StringUtils.isBlank(cwGlVouchermaxno.getMaxno())) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.MAXNO_INFO_NOTFOUND.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.MAXNO_INFO_NOTFOUND));
        }
        String voucherno = Integer.valueOf(cwGlVouchermaxno.getMaxno()) + 1 + "";
        cwGlVoucherWeb.setVoucherno(voucherno);

        // 调用新增凭证服务
        RestfulResponse<Object, CurrencyMeta> addCwGlVoucher = cwGlVoucherService.addCwGlVoucher(cwGlVoucherWeb);
        // 新增凭证单据明细对应关系等
            /*if (SysConstants.CODE.SUCCESS == addCwGlVoucher.getCode().intValue()) {
                
                CwBdRelation cwBdRelation = new CwBdRelation();
                cwBdRelation.setPkRelation(SnowflakeIdWorker.getInstance().nextIdString());
                cwBdRelation.setPkSrcbilltype(cwBdVouchtemp.getPkBilltype());
                cwBdRelation.setPkSrcbillpk(thirdBusiBenlistInfo.getId());
                cwBdRelation.setPkVoucher((String) addCwGlVoucher.getData());
                cwBdRelation.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
                //cwBdRelation.setCreateUser(userId);
                cwBdRelation.setCreateTime(new Date());
                // 新增凭证单据明细对应关系
                cwBdRelationMapper.insert(cwBdRelation);
                // 自动审核记账(自动审核记账失败不影响整体功能)
                try {
                    automaticAuditAndSign(addCwGlVoucher, cwGlVoucherWeb, userId,map);
                } catch (Exception e) {
                    log.error("自动审核记账异常>>>>>>>>>",e);
                }
            }*/

        return addCwGlVoucher;
    }

    /**
     * 功能描述:固有代垫组装分录信息
     *
     * @param fundsFlowInfoGydds
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author likai
     * @data 2020年4月15日下午3:18:46
     * 修改日志
     */
    private RestfulResponse<Object, CurrencyMeta> getDetailInfoGydd(List<CwGlDetailWeb> cwGlDetailList, FundProjectInfoGydd fundProjectInfoGydd, CwBdVouchtemp cwBdVouchtemp) {
        // 查询凭证分录
        List<CwBdVouchtempB> cwBdVouchtempBList = cwBdVouchtempBMapper.selectByPkVouchtemp(cwBdVouchtemp.getPkVouchtemp());
        RestfulResponse<Object, CurrencyMeta> setCwGlDetailWebGydd = null;
        for (CwBdVouchtempB cwBdVouchtempB : cwBdVouchtempBList) {
            setCwGlDetailWebGydd = setCwGlDetailWebGydd(cwGlDetailList, fundProjectInfoGydd, cwBdVouchtempB);
        }
        if (SysConstants.CODE.FAIL == setCwGlDetailWebGydd.getCode().intValue()) {
            return setCwGlDetailWebGydd;
        }
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * 功能描述:固有代垫生成分录信息
     *
     * @param fundsFlowInfoGydds
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author likai
     * @data 2020年4月15日下午3:18:46
     * 修改日志
     */
    private RestfulResponse<Object, CurrencyMeta> setCwGlDetailWebGydd(List<CwGlDetailWeb> cwGlDetailList, FundProjectInfoGydd fundProjectInfoGydd, CwBdVouchtempB cwBdVouchtempB) {
        // 查询对应科目详情
        CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectByPrimaryKey(cwBdVouchtempB.getPkAccsubj());
        Map<String, Object> map = getParmMapGydd(fundProjectInfoGydd);
        //  BigDecimal orimoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getOrimoney(), map);
        //  BigDecimal basemoney = FinanceExpUtil.getExpResult(cwBdVouchtempB.getBasemoney(), map);
        // 原币金额
        BigDecimal orimoney = fundProjectInfoGydd.getBalance();
        // 本币金额
        BigDecimal basemoney = fundProjectInfoGydd.getBalance();
        if (orimoney == null || basemoney == null) {
            return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                    FinanceStatusCode.EXP_CALCULATION_FAILURE.message(),
                    MetaDataUtil.getMeta(tracer, FinanceStatusCode.EXP_CALCULATION_FAILURE));
        }
        // 凭证分录信息实体
        CwGlDetailWeb cwGlDetailWeb = new CwGlDetailWeb();
        String abstracts = cwBdVouchtempB.getAbstracts();
        cwGlDetailWeb.setAbstracts(abstracts);
        cwGlDetailWeb.setPkAccsubj(cwBdAccsubj.getPkAccsubj());
        cwGlDetailWeb.setSubjcode(cwBdAccsubj.getSubjcode());// 必传
        cwGlDetailWeb.setSubjname(cwBdAccsubj.getSubjname());
        cwGlDetailWeb.setPkCurrtype(cwBdVouchtempB.getPkCurrtype());
        if (FinanceDictConsts.Cwjdfx.JIE.equals(cwBdVouchtempB.getDirection())) {
            if ("224102".equals(cwBdAccsubj.getSubjcode())) {
                cwGlDetailWeb.setDebitamount(orimoney);
                cwGlDetailWeb.setLocaldebitamount(basemoney);
                cwGlDetailWeb.setCreditamount(new BigDecimal("0"));
                cwGlDetailWeb.setLocalcreditamount(new BigDecimal("0"));
            } else {
                cwGlDetailWeb.setDebitamount(orimoney.multiply(new BigDecimal(-1)));
                cwGlDetailWeb.setLocaldebitamount(basemoney.multiply(new BigDecimal(-1)));
                cwGlDetailWeb.setCreditamount(new BigDecimal("0"));
                cwGlDetailWeb.setLocalcreditamount(new BigDecimal("0"));
            }

        } else {
            cwGlDetailWeb.setDebitamount(new BigDecimal("0"));
            cwGlDetailWeb.setLocaldebitamount(new BigDecimal("0"));
            cwGlDetailWeb.setCreditamount(orimoney.multiply(new BigDecimal(-1)));
            cwGlDetailWeb.setLocalcreditamount(basemoney.multiply(new BigDecimal(-1)));
        }
        List<CwGlFreevalue> cwGlFreevalueList = new ArrayList<CwGlFreevalue>();
        // 查询凭证模板分录辅助配置
        List<CwBdVouchtempF> cwBdVouchtempFList = CwBdVouchtempFMapper.selectByPkVouchtempB(cwBdVouchtempB.getPkVouchtempB());
        for (CwBdVouchtempF cwBdVouchtempF : cwBdVouchtempFList) {
            CwGlFreevalue cwGlFreevalue = new CwGlFreevalue();
            cwGlFreevalue.setChecktype(cwBdVouchtempF.getPkAccass());
            // 获得辅助值
            String methodValue = null;
            try {
                // 辅助值(可能有判断条件)
                    /*String assvalue = getAssValue(cwBdVouchtempF,fundsFlowInfo);
                    if (StringUtils.isBlank(assvalue)) {// 如果为空则跳过
                        continue;
                    }
                    methodValue = (String) FinancePublicUtil.getMethodValue(fundsFlowInfo,assvalue);*/
            } catch (Exception e) {
                log.error("获取辅助值失败>>>>>>>>>", e);
            }
            if (StringUtils.isBlank(methodValue)) {
                return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, cwBdVouchtempF.getAssvalue() + FinanceStatusCode.ASSVALUE_IS_NULL.message(),
                        MetaDataUtil.getMeta(tracer, FinanceStatusCode.ASSVALUE_IS_NULL));
            }
            cwGlFreevalue.setCheckvalue(methodValue);
            cwGlFreevalueList.add(cwGlFreevalue);
        }
        cwGlDetailWeb.setCwGlFreevalueList(cwGlFreevalueList);// 辅助信息
        // TODO 如果分录金额为0就过滤掉(先按这种模式来)
        if (cwGlDetailWeb.getLocalcreditamount().compareTo(BigDecimal.ZERO) != 0 || cwGlDetailWeb.getLocaldebitamount().compareTo(BigDecimal.ZERO) != 0) {
            cwGlDetailList.add(cwGlDetailWeb);
        }
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
                MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * 功能描述:固有代垫获取表达式参数值
     *
     * @param fundsFlowInfoGydds
     * @return RestfulResponse<Object, CurrencyMeta>
     * @author likai
     * @data 2020年4月15日下午3:18:46
     * 修改日志
     */
    private Map<String, Object> getParmMapGydd(FundProjectInfoGydd fundProjectInfoGydd) {
        // 表达式计算参数
        Map<String, Object> map = new HashMap<>();
        map.put("GHDDKJE", fundProjectInfoGydd.getBalance() == null ? new BigDecimal("0") : fundProjectInfoGydd.getBalance());
        return map;
    }


    public RestfulResponse<Object, CurrencyMeta> addCwGlVoucherBatch(List<CwGlVoucherImport> list) {
        for (CwGlVoucherImport cwGlVoucherImport: list) {
            // cw_bd_scenariorelation cw_bd_scenario表加新字段 CwBdScenario实体类加新字段 xxxx
            CwBdScenario cwBdScenario = cwBdScenarioMapper.selectByJym(cwGlVoucherImport.getTradeCode());
            FundsFlowInfo fundsFlowInfo = new FundsFlowInfo();
            fundsFlowInfo.setCostType(cwGlVoucherImport.getTempType());
            // ------------------------
            initScenariofield();
            String cwBdVouchtempKey = getCwBdVouchtemp(fundsFlowInfo, cwBdScenario);
            CwBdVouchtemp cwBdVouchtemp = cwBdVouchtempMapper.selectByCode(cwBdVouchtempKey);
            List<CwBdVouchtempB> cwBdVouchtempBS = cwBdVouchtempBMapper.selectByPkVouchtemp(cwBdVouchtemp.getPkVouchtemp());

            CwGlVoucherTempRequest cwGlVoucherTempRequest = new CwGlVoucherTempRequest();
            cwGlVoucherTempRequest.setBatchNo(cwGlVoucherImport.getBatchNo());
            cwGlVoucherTempRequest.setPkSystem("01");
            cwGlVoucherTempRequest.setVoucherType(cwGlVoucherImport.getTempType());
            List<CwGlVoucher> cwGlVouchers = cwGlVoucherMapper.searchVoucherByBatchNo(cwBdVouchtemp, cwGlVoucherTempRequest);


            if (cwGlVouchers != null && cwGlVouchers.size() > 0) {
                int i = cwGlVoucherMapper.insertVoucherBatch(cwGlVouchers);

                if (i > 0) {
                    cwBdVouchtempBS.forEach((cwBdVouchtempB -> {
                        List<CwBdVouchtempF> cwBdVouchtempFS = CwBdVouchtempFMapper.selectByPkVouchtempB(cwBdVouchtempB.getPkVouchtempB());

                        boolean hasItem = true;
                        if (cwBdVouchtempFS == null || cwBdVouchtempFS.size() <= 0) {
                            hasItem = false;
                        }
                        cwGlVoucherTempRequest.setHasItem(hasItem);
                        cwGlVoucherTempRequest.setDirection(cwBdVouchtempB.getDirection());
                        cwGlVoucherTempRequest.setIndex(cwBdVouchtempBS.indexOf(cwBdVouchtempB) + 1 + "");
                        final List<CwGlDetail> cwGlDetails = cwGlDetailMapper.searchCwGlDetailByBatchNo(cwBdVouchtempB, cwGlVoucherTempRequest);
                        int j = cwGlDetailMapper.insertCwGlDetailBatch(cwGlDetails);
                        if (j > 0) {
                            if (cwBdVouchtempFS != null && cwBdVouchtempFS.size() > 0) {
                                cwBdVouchtempFS.forEach(cwBdVouchtempF -> {
    //                                String valuename = "";
    //                                if (StringUtils.isBlank(cwBdVouchtempF.getPkAccass())) {
    //                                    CwBdAccassitem cwBdAccassitem = cwBdAccassitemMapper.selectByPrimaryKey(cwBdVouchtempF.getPkAccass());
    //                                    if (cwBdAccassitem != null) {
    //                                        String sql = "select " + cwBdAccassitem.getCodefield() + " as checkname from " + cwBdAccassitem.getTablecode() +
    //                                                "  where " + cwBdAccassitem.getPkfield() + " = '" + cwBdVouchtempF.getAssvalue() + "'";
    //                                        valuename = cwBdAccassitemMapper.selectCheckname(sql);
    //                                        cwGlVoucherTempRequest.setValueName(valuename);
    //                                    }
    //                                }
                                    cwGlVoucherTempRequest.setIndex(cwBdVouchtempFS.indexOf(cwBdVouchtempF) + 1 + "");
                                    List<CwGlFreevalue> cwGlFreevalues = cwGlFreevalueMapper.selectCwGlFreevalueBatchByTemp(cwBdVouchtempF, cwGlVoucherTempRequest);
                                    cwGlFreevalues.forEach(cwGlFreevalue -> {
                                        if (cwGlFreevalue.getCheckvalue() != null) {
                                            /*String sql = "select "+cwBdAccassitem.getCodefield()+" as checkname from "+ cwBdAccassitem.getTablecode()+
                                                    "  where "+cwBdAccassitem.getPkfield() + " = '"+y.getCheckvalue()+"'";
                                            String res = cwBdAccassitemMapper.selectCheckname(sql);*/
                                        }
                                    });
                                    cwGlFreevalueMapper.insertCwGlFreevalueBatch(cwGlFreevalues);

                                });
                            }
                        }

                    }));
                    CwBdRecordSerial cwBdRecordSerial = new CwBdRecordSerial();
                    cwBdRecordSerial.setBatchNo(cwGlVoucherImport.getBatchNo());
                    cwBdRecordSerial.setTradecode(cwGlVoucherImport.getTradeCode());
                    cwBdRecordSerial.setSignType("1");
                    cwBdRecordSerialMapper.insertCwBdRecordSerialByBatchNo(cwBdRecordSerial,cwGlVoucherImport.getTempType());

                }
            }
        }
        return null;
    }


    
}
