package com.zzsmart.qomo.kn.cost.manage.plugin;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.zzsmart.qomo.kn.cost.manage.entity.*;
import com.zzsmart.qomo.kn.cost.manage.mapper.AppSceneCostSapZcorcMapper;
import com.zzsmart.qomo.kn.cost.manage.plugin.webservice.SAPOrderServiceImpl;
import com.zzsmart.qomo.kn.cost.manage.service.*;
import com.zzsmart.qomo.kn.cost.manage.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
@Transactional
public class CostEffectiveService {

    private static final Logger logger = LoggerFactory.getLogger(CostEffectiveService.class);

    @Autowired
    private Environment env;

    @Autowired
    private IAppSceneCostSapZcorcService iAppSceneCostSapZcorcService;

    @Autowired
    private IAppSceneCostMaterialService iAppSceneCostMaterialService;

    @Autowired
    private IAppSceneCostSapHourRateService iAppSceneCostSapHourRateService;

    @Autowired
    private IAppSceneCostSapAfruService iAppSceneCostSapAfruService;

    @Autowired
    private IAppSceneCostStandardResultService iAppSceneCostStandardResultService;

    @Autowired
    private IAppSceneCostHourRateService iAppSceneCostHourRateService;

    @Autowired
    private IAppSceneCostBomRelevancyService iAppSceneCostBomRelevancyService;

    @Autowired
    private IAppSceneCostStandardProductprocessService iAppSceneCostStandardProductprocessService;

    @Autowired
    private IAppSceneCostStandardBomService iAppSceneCostStandardBomService;

    @Autowired
    private IAppSceneCostMiningDiffService iAppSceneCostMiningDiffService;
    @Autowired
    private IAppSceneCostMiningResultService iAppSceneCostMiningResultService;
    @Autowired
    private IAppSceneCostMiningAufnrService iAppSceneCostMiningAufnrService;
    @Autowired
    private IAppSceneCostMiningMaterialService iAppSceneCostMiningMaterialService;
    @Autowired
    private IAppSceneCostMiningReasonService iAppSceneCostMiningReasonService;
    @Autowired
    private IAppSceneCostSapZtmmx004Service iAppSceneCostSapZtmmx004Service;


    public Map<String, Map<String, ZcorcMaterialDiff>> rlayerMatnrMap = new HashMap<>();
    public Map<String, Map<String, ZcorcAufnrDiff>> layerAufnrMap = new HashMap<>();
    public Map<String, List<HiveSapZcorc>> tempSapZcorcList = new HashedMap();
    //public Map<String, String> auartMap = new HashedMap();
    public Map<String, List<HiveSapAfru>> afruMap = new HashedMap();//报工单
    //public Map<String, List<SrmPrice>> priceMap = new HashedMap();
    public Map<String, AppSceneCostMaterial> materialMap = new HashedMap();

    public Map<String, ZcorcAufnr> zcorcAufnrMap = new HashMap<>();
    public Map<String, ZcorcMatnr> zcorcMatnrMap = new HashMap<>();

    public Map<String, VersionTmp> versionTmpMap = new HashMap<>();

    public Map<String, AppSceneCostMiningReason> miningReasonMap = new HashedMap();

    public Map<String,List<AppSceneCostSapZtmmx004>> mapZtmmx004 = new HashMap<>();

    //public Map<String, CostCenter> costCenterMap = new HashMap<>();
    //参考层级
    //public Set<String> rlayers = new HashSet<>();
    public TreeSet<String> rlayers = new TreeSet<>(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            if (o1.equals(o2)) {
                return 0;
            } else if (o1.length() < o2.length()) {
                return 1;
            } else {
                return -1;
            }
            //return o1<o2;   //改写排序规则，降序排序
        }
    });

    private Map<String, UnitCost> tempUniCost = new HashMap<>();

    public JSONObject ConvertTolowercase(JSONObject obj) {
        JSONObject result = new JSONObject();
        for (Map.Entry<String, Object> entry : obj.entrySet()) {
            // System.out.println(entry.getKey() + ":" + entry.getValue());
            String newkey = entry.getKey().toLowerCase();
            if (newkey.equals("pspsppnr")) {
                newkey = "psPspPnr";
            }
            result.put(newkey, entry.getValue());
        }
        return result;
    }

    public double ConvertStringtoDouble(String value) {
        boolean neg = false;
        if (value.indexOf("-") != -1) {
            neg = true;
        }
        String item = value.replace("-", "");
        if (neg) {
            return 0 - Double.parseDouble(item);
        } else {
            return Double.parseDouble(item);
        }
    }

    public String getNextMonth(String ymonth) {
        String result = ymonth;
        if (result.length() == 6) {
            int year = Integer.parseInt(result.substring(0, 4));
            int month = Integer.parseInt(result.substring(4, 6));
            if (month == 12) {
                month = 1;
                year += 1;
            } else {
                month += 1;
            }
            result = String.valueOf(year);
            if (month < 10) {
                result += "0" + month;
            } else {
                result += month;
            }
        }
        return result;
    }

    public String getLastMonth(String ymonth) {
        String result = ymonth;
        if (result.length() == 6) {
            int year = Integer.parseInt(result.substring(0, 4));
            int month = Integer.parseInt(result.substring(4, 6));
            if (month > 6) {
                month = month - 6;
                //year += 1;
            } else {
                month = month + 6;
                year = year - 1;
            }
            result = String.valueOf(year);
            if (month < 10) {
                result += "0" + month;
            } else {
                result += month;
            }
        }
        return result;
    }

    public void LoadMiningReason() {
        List<AppSceneCostMiningReason> reasons=iAppSceneCostMiningReasonService.list();
        for (AppSceneCostMiningReason reason:reasons){
            miningReasonMap.put(reason.getCode(), reason);
        }
    }

    public void fixversion(String version){
        QueryWrapper<AppSceneCostSapZcorc> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("version",version);
        List<AppSceneCostSapZcorc> zcorcs=iAppSceneCostSapZcorcService.list(queryWrapper);
        if(zcorcs.size()>0) {
            AppSceneCostSapZcorc zcorc=zcorcs.get(0);
            FillNums(zcorcs,zcorc.getYmonth());
        }
        int index=0;
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            logger.info(index+"/"+zcorcs.size());
            iAppSceneCostSapZcorcService.updateById(zcorc);
            index++;
        }
        //iAppSceneCostSapZcorcService.updateBatchById(zcorcs);
    }

    Map<String,AppSceneCostSapZcorc> mapAufnr=new HashMap<>();
    public void FillAufnrs(List<AppSceneCostSapZcorc> zcorcs,String ymonth){

        QueryWrapper<AppSceneCostSapHourRate> queryWrapper1=new QueryWrapper<>();
        //queryWrapper1.eq("ym",ymonth);
        queryWrapper1.like("center_code","7100%");
        List<AppSceneCostSapHourRate> appSceneCostSapHourRates = iAppSceneCostSapHourRateService.list(queryWrapper1);
        Map<String,AppSceneCostSapHourRate> mapHour = new HashMap<>();
        for (AppSceneCostSapHourRate hourRate:appSceneCostSapHourRates){
            String key = hourRate.getCenterCode()+"-"+hourRate.getYm();
            mapHour.put(key,hourRate);
        }

        for (AppSceneCostSapHourRate row : appSceneCostSapHourRates) {
            UnitCost unitCost = new UnitCost();
            double minute = 60;
            unitCost.rgfv = row.getRgfv().doubleValue() / minute;
            unitCost.sbfv = row.getSbfv().doubleValue() / minute;
            unitCost.rdfv = row.getRdfv().doubleValue() / minute;
            unitCost.flfv = row.getFlfv().doubleValue() / minute;
            unitCost.qtfv = row.getQtfv().doubleValue() / minute;

            String code = row.getCenterCode();
            String month = row.getYm();
            tempUniCost.put(code + "." + month, unitCost);
        }

        int index=0;
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            logger.info("aufnr "+index+"/"+zcorcs.size());
            index++;
            if(zcorc.getMatnr().equals(zcorc.getIdnrk())){
                if(!mapAufnr.containsKey(zcorc.getAufnr())){
                    QueryWrapper<AppSceneCostSapAfru> queryWrapper=new QueryWrapper<>();
                    queryWrapper.eq("aufnr",zcorc.getAufnr());
                    List<AppSceneCostSapAfru> list=iAppSceneCostSapAfruService.list(queryWrapper);
                    double rggs=0;
                    double flgs=0;
                    double rdgs=0;
                    double sbgs=0;
                    double qtgs=0;
                    double rgcost = 0;
                    double flcost = 0;
                    double rdcost = 0;
                    double sbcost = 0;
                    double qtcost = 0;
                    for (AppSceneCostSapAfru afru:list){
                        rggs+=afru.getIsm03().doubleValue();
                        sbgs+=afru.getIsm02().doubleValue();
                        flgs+=afru.getIsm05().doubleValue();
                        rdgs+=afru.getIsm04().doubleValue();
                        qtgs+=afru.getIsm06().doubleValue();
                        String ym = afru.getYm();
                        String key = afru.getKostl()+"-"+ym;
                        if(mapHour.containsKey(key)){
                            AppSceneCostSapHourRate hourRate=mapHour.get(key);
                            rgcost+=hourRate.getRgfv().doubleValue()*afru.getIsm03().doubleValue();
                            flcost+=hourRate.getFlfv().doubleValue()*afru.getIsm05().doubleValue();
                            rdcost+=hourRate.getRdfv().doubleValue()*afru.getIsm04().doubleValue();
                            sbcost+=hourRate.getSbfv().doubleValue()*afru.getIsm02().doubleValue();
                            qtcost+=hourRate.getQtfv().doubleValue()*afru.getIsm06().doubleValue();
                        }
                    }
                    zcorc.setRggs(new BigDecimal(rggs));
                    zcorc.setRgfv(new BigDecimal(rggs!=0?rgcost/rggs:0));
                    zcorc.setSbgs(new BigDecimal(sbgs));
                    zcorc.setSbfv(new BigDecimal(sbgs!=0?sbcost/sbgs:0));
                    zcorc.setFlgs(new BigDecimal(flgs));
                    zcorc.setFlfv(new BigDecimal(flgs!=0?flcost/flgs:0));
                    zcorc.setRdgs(new BigDecimal(rdgs));
                    zcorc.setRdfv(new BigDecimal(rdgs!=0?rdcost/rdgs:0));
                    zcorc.setQtgs(new BigDecimal(qtgs));
                    zcorc.setQtfv(new BigDecimal(qtgs!=0?qtcost/qtgs:0));
                    mapAufnr.put(zcorc.getAufnr(),zcorc);
                }else{
                    AppSceneCostSapZcorc zcorc1=mapAufnr.get(zcorc.getAufnr());
                    zcorc.setRggs(zcorc1.getRggs());
                    zcorc.setRgfv(zcorc1.getRgfv());
                    zcorc.setSbgs(zcorc1.getSbgs());
                    zcorc.setSbfv(zcorc1.getSbfv());
                    zcorc.setFlgs(zcorc1.getFlgs());
                    zcorc.setFlfv(zcorc1.getFlfv());
                    zcorc.setRdgs(zcorc1.getRdgs());
                    zcorc.setRdfv(zcorc1.getRgfv());
                    zcorc.setQtgs(zcorc1.getQtgs());
                    zcorc.setQtfv(zcorc1.getQtfv());
                }
            }
        }
    }

    public void FillNums3(List<AppSceneCostSapZcorc> zcorcs,String ymonth){
        FillAufnrs(zcorcs,ymonth);
        if(zcorcs.size()>0){
            logger.info("fillnums "+zcorcs.get(0).getAufnr());
            if(zcorcs.get(0).getAufnr()==null){
                return;
            }
        }
        String topmantr = "";
        //填充level
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            String[] values = zcorc.getLayer().split("-");
            int level = (values.length-1)/2;
            zcorc.setLevel(level);
            if(zcorc.getPlayer().equals("0")){
                zcorc.setPnum(new BigDecimal(1));
                zcorc.setLevel(0);
                zcorc.setMatnrnum(new BigDecimal(1));
                zcorc.setAufnrnum(new BigDecimal(1));
                topmantr = zcorc.getMatnr();
            }
        }
        //1.第一步，填充aufnrtotal
        //kmonth 等于 0 的是订单，将player相等的归为一组
//        Map<String,List<AppSceneCostSapZcorc>> mapZcorc = new HashMap<>();
//        for (AppSceneCostSapZcorc appSceneCostSapZcorc:zcorcs){
//            //String kmonth = appSceneCostSapZcorc.getKmonth();
//            if(appSceneCostSapZcorc.getPlayer().equals("0")){
//                continue;
//            }
//            if(!appSceneCostSapZcorc.getKmonth().equals("000000")){
//                continue;
//            }
//            String player = appSceneCostSapZcorc.getPlayer();
//            //String player = appSceneCostSapZcorc.getMatnr();
//            if(mapZcorc.containsKey(player)){
//                List<AppSceneCostSapZcorc> items = mapZcorc.get(player);
//                items.add(appSceneCostSapZcorc);
//                mapZcorc.put(player,items);
//            }else{
//                List<AppSceneCostSapZcorc> items = new ArrayList<>();
//                items.add(appSceneCostSapZcorc);
//                mapZcorc.put(player,items);
//            }
//        }
//        Map<String,BigDecimal> mapNum = new HashedMap();
//        for (String player:mapZcorc.keySet()){
//            double totalmenge = 0;
//            List<AppSceneCostSapZcorc> items = mapZcorc.get(player);
//            for (AppSceneCostSapZcorc zcorc:items){
//                totalmenge+=zcorc.getMenge().doubleValue();
//            }
//            mapNum.put(player,new BigDecimal(totalmenge));
//        }
//        for (AppSceneCostSapZcorc zcorc:zcorcs){
//            if(mapNum.containsKey(zcorc.getPlayer())){
//                zcorc.setAufnrtotal(mapNum.get(zcorc.getPlayer()));
//            }
//        }
//        //临时保存的记录，用于计算nums
        Map<String,AppSceneCostSapZcorc> numZcorc = new HashMap<>();
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            numZcorc.put(zcorc.getLayer(),zcorc);
        }
        //根据组件对结果进行分组
        Map<String,List<AppSceneCostSapZcorc>> pairMap = new HashMap<>();
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            String pair = zcorc.getIdnrk();
            if(zcorc.getMatnr().equals(zcorc.getIdnrk())){
                continue;
            }
            if(pairMap.containsKey(pair)){
                List<AppSceneCostSapZcorc> items = pairMap.get(pair);
                items.add(zcorc);
                pairMap.put(pair,items);
            }else{
                List<AppSceneCostSapZcorc> items = new ArrayList<>();
                items.add(zcorc);
                pairMap.put(pair,items);
            }
        }
        //构建物料号，avgnum的结构
        Map<String,Double> matnrNum=new HashMap<>();
        matnrNum.put(topmantr,1.0);

        //
        Map<String,AppSceneCostSapZcorc> matnridnrkNum=new HashMap<>();
        //记录aufnrtotal,aufnrnum
        Map<String,Double> matnrTotal=new HashMap<>();


        //1.根据level,逐层填充，先填充pnum,
        //2.matnr = pnum*unmng  如果是物料 pnum = 上层的aufnrnum 如果是订单 pnum = 上层的matnrnum
        //3.aufnr = menge*pnum/aufnrtotal
        Map<Integer,List<AppSceneCostSapZcorc>> levelZcorcs = new HashMap<>();
        for (AppSceneCostSapZcorc appSceneCostSapZcorc:zcorcs){
            if(appSceneCostSapZcorc.getPlayer().equals("0")){
                continue;
            }
            int level = appSceneCostSapZcorc.getLevel();
            if(levelZcorcs.containsKey(level)){
                List<AppSceneCostSapZcorc> items = levelZcorcs.get(level);
                items.add(appSceneCostSapZcorc);
                levelZcorcs.put(level,items);
            }else{
                List<AppSceneCostSapZcorc> items = new ArrayList<>();
                items.add(appSceneCostSapZcorc);
                levelZcorcs.put(level,items);
            }
        }
        Map<String,BigDecimal> mapMng=new HashMap<>();
        for (int level:levelZcorcs.keySet()){
            List<AppSceneCostSapZcorc> zcorcList = levelZcorcs.get(level);
            for (AppSceneCostSapZcorc item:zcorcList){
                String matnr = item.getMatnr();
                String idnrk = item.getIdnrk();
                String aufnr = item.getAufnr();
                if(idnrk.equals("41030020002800")){
                    logger.info("41030020002800");
                }
                AppSceneCostSapZcorc zcorc = numZcorc.get(item.getLayer());
                if(zcorc!=null){
                    String key = matnr+"-"+idnrk+"-"+aufnr;
                    //订单数量 根据订单号去重
                    if(!mapMng.containsKey(key)){
                        mapMng.put(key,item.getPsmng());
                        zcorc.setAufnrmng(item.getPsmng());
                    }else{
                        zcorc.setAufnrmng(new BigDecimal(0));
                    }
                    if(matnrNum.containsKey(matnr)){
                        zcorc.setPnum(new BigDecimal(matnrNum.get(matnr)));
                    }
                    if(matnrNum.containsKey(idnrk)){
                        zcorc.setTotalnum(new BigDecimal(matnrNum.get(idnrk)));
                        String pair = matnr+"-"+idnrk;
                        if(matnridnrkNum.containsKey(pair)){
                            //zcorc.setAvgnum(new BigDecimal(matnridnrkNum.get(pair)));
                            AppSceneCostSapZcorc sapZcorc=matnridnrkNum.get(pair);
                            zcorc.setAvgnum(sapZcorc.getAvgnum());
                            zcorc.setAufnrtotal(sapZcorc.getAufnrtotal());
                            zcorc.setAufnrnum(sapZcorc.getAufnrnum());
                            zcorc.setAvgprice(sapZcorc.getAvgprice());
                            zcorc.setTotalprice(sapZcorc.getTotalprice());
                        }
                        if(matnrTotal.containsKey(idnrk)){
                            zcorc.setTotalprice(new BigDecimal(matnrTotal.get(idnrk)));
                        }
                    }else{
                        List<AppSceneCostSapZcorc> items = pairMap.get(idnrk);
                        //再根据父物料进行分组
                        Map<String,List<AppSceneCostSapZcorc>> pmatnrMap = new HashMap<>();
                        for (AppSceneCostSapZcorc it:items){
                            if(pmatnrMap.containsKey(it.getMatnr())){
                                List<AppSceneCostSapZcorc> its = pmatnrMap.get(it.getMatnr());
                                its.add(it);
                                pmatnrMap.put(it.getMatnr(),its);
                            }else{
                                List<AppSceneCostSapZcorc> its = new ArrayList<>();
                                its.add(it);
                                pmatnrMap.put(it.getMatnr(),its);
                            }
                        }
                        Map<String,Double> pmatnrnumMap  = new HashMap<>();
                        double totalamount=0;
                        double totalmenge=0;
                        //对每一个父物料组，进行计算
                        for (String pmatnr:pmatnrMap.keySet()){
                            //如果同一个父物料在多层，只取第一个

                            //父物料的加权数量
                            double pnum = 1;
                            if(matnrNum.containsKey(pmatnr)){
                                pnum = matnrNum.get(pmatnr);
                            }
                            List<AppSceneCostSapZcorc> citems = pmatnrMap.get(pmatnr);
                            String toplayer = "";
                            if(citems.size()>0){
                                AppSceneCostSapZcorc zcorc1 = citems.get(0);
                                String layer = zcorc1.getLayer();
                                String[] names = layer.split("-");
                                if(names.length>3){
                                    for (int i=0;i<names.length-2;++i){
                                        toplayer+=names[i];
                                        toplayer+="-";
                                    }
                                }
                            }
                            //父物料工单数量
                            double aufnrtotal=0;
                            //子物料领用数量
                            double menge=0;
                            double amount=0;
                            Map<String,Double> aufnrmap=new HashMap<>();
                            for (AppSceneCostSapZcorc cit:citems){
                                if(!aufnrmap.containsKey(cit.getAufnr())){
                                    aufnrmap.put(cit.getAufnr(),cit.getPsmng().doubleValue());
                                    aufnrtotal+=cit.getPsmng().doubleValue();
                                }
                                if(cit.getLayer().indexOf(toplayer)!=-1||toplayer.equals("")) {
                                    menge += cit.getMenge().doubleValue();
                                    amount += cit.getRkst001().doubleValue();
                                    AppSceneCostSapZcorc zcorc2 = numZcorc.get(cit.getLayer());
                                    if(zcorc2!=null){
                                        zcorc2.setAufnrmenge(cit.getMenge());
                                    }
                                }
                            }
                            double avgnum = menge*pnum/aufnrtotal;
                            double avgprice = amount;
                            pmatnrnumMap.put(pmatnr,avgnum);
                            String pair = pmatnr+"-"+idnrk;

                            AppSceneCostSapZcorc sapZcorc=new AppSceneCostSapZcorc();
                            sapZcorc.setAvgprice(new BigDecimal(avgprice));
                            sapZcorc.setAvgnum(new BigDecimal(avgnum));
                            sapZcorc.setAufnrtotal(new BigDecimal(aufnrtotal));
                            sapZcorc.setAufnrnum(new BigDecimal(menge));
                            matnridnrkNum.put(pair,sapZcorc);

                            totalamount+=sapZcorc.getAvgprice().doubleValue();
                            totalmenge+=sapZcorc.getAufnrnum().doubleValue();
                        }
                        double totalnum = 0;
                        for (String pnum:pmatnrnumMap.keySet()){
                            totalnum+=pmatnrnumMap.get(pnum);
                        }
                        matnrNum.put(idnrk,totalnum);
                        zcorc.setTotalnum(new BigDecimal(totalnum));
                        String pair = matnr+"-"+idnrk;
                        //double totalamount=0;
                        //double totalmenge=0;
                        if(matnridnrkNum.containsKey(pair)){
                            AppSceneCostSapZcorc sapZcorc=matnridnrkNum.get(pair);
                            zcorc.setAvgnum(sapZcorc.getAvgnum());
                            zcorc.setAufnrtotal(sapZcorc.getAufnrtotal());
                            zcorc.setAufnrnum(sapZcorc.getAufnrnum());
                            zcorc.setAvgprice(sapZcorc.getAvgprice());
                            //totalamount+=sapZcorc.getAvgprice().doubleValue();
                            //totalmenge+=sapZcorc.getAufnrnum().doubleValue();
                        }
                        double totalprice = totalamount/totalmenge;
                        zcorc.setTotalprice(new BigDecimal(totalprice));
                        matnrTotal.put(idnrk,totalprice);
                    }
                    numZcorc.put(item.getLayer(),zcorc);
                }
            }
        }
        for (AppSceneCostSapZcorc item:zcorcs){
            if(item.getIdnrk().equals("41030020002800")){
                logger.info("41030020002800");
            }
            AppSceneCostSapZcorc zcorc = numZcorc.get(item.getLayer());
            item.setAufnrnum(zcorc.getAufnrnum());
            item.setMatnrnum(zcorc.getMatnrnum());
            item.setPnum(zcorc.getPnum());
            if(item.getMatnrnum()!=null&&(item.getMatnrnum().compareTo(BigDecimal.ZERO)==0)){
                item.setContent("可能存在替代料情况");
            }
        }
    }

    public void FillNums(List<AppSceneCostSapZcorc> zcorcs,String ymonth){
        if(zcorcs.size()>0){
            logger.info("fillnums "+zcorcs.get(0).getAufnr());
            if(zcorcs.get(0).getAufnr()==null){
                return;
            }
        }
        //填充level
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            String[] values = zcorc.getLayer().split("-");
            int level = (values.length-1)/2;
            zcorc.setLevel(level);
            if(zcorc.getPlayer().equals("0")){
                zcorc.setPnum(new BigDecimal(1));
                zcorc.setLevel(0);
                zcorc.setMatnrnum(new BigDecimal(1));
                zcorc.setAufnrnum(new BigDecimal(1));
            }
        }
        //1.第一步，填充aufnrtotal
        //kmonth 等于 0 的是订单，将player相等的归为一组
        Map<String,List<AppSceneCostSapZcorc>> mapZcorc = new HashMap<>();
        for (AppSceneCostSapZcorc appSceneCostSapZcorc:zcorcs){
            //String kmonth = appSceneCostSapZcorc.getKmonth();
            if(appSceneCostSapZcorc.getPlayer().equals("0")){
                continue;
            }
            if(!appSceneCostSapZcorc.getKmonth().equals("000000")){
                continue;
            }
            String player = appSceneCostSapZcorc.getPlayer();
            //String player = appSceneCostSapZcorc.getMatnr();
            if(mapZcorc.containsKey(player)){
                List<AppSceneCostSapZcorc> items = mapZcorc.get(player);
                items.add(appSceneCostSapZcorc);
                mapZcorc.put(player,items);
            }else{
                List<AppSceneCostSapZcorc> items = new ArrayList<>();
                items.add(appSceneCostSapZcorc);
                mapZcorc.put(player,items);
            }
        }
        Map<String,BigDecimal> mapNum = new HashedMap();
        for (String player:mapZcorc.keySet()){
            double totalmenge = 0;
            List<AppSceneCostSapZcorc> items = mapZcorc.get(player);
            for (AppSceneCostSapZcorc zcorc:items){
                totalmenge+=zcorc.getMenge().doubleValue();
            }
            mapNum.put(player,new BigDecimal(totalmenge));
        }
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            if(mapNum.containsKey(zcorc.getPlayer())){
                zcorc.setAufnrtotal(mapNum.get(zcorc.getPlayer()));
            }
        }
        //临时保存的记录，用于计算nums
        Map<String,AppSceneCostSapZcorc> numZcorc = new HashMap<>();
        for (AppSceneCostSapZcorc zcorc:zcorcs){
            numZcorc.put(zcorc.getLayer(),zcorc);
        }
        //1.根据level,逐层填充，先填充pnum,
        //2.matnr = pnum*unmng  如果是物料 pnum = 上层的aufnrnum 如果是订单 pnum = 上层的matnrnum
        //3.aufnr = menge*pnum/aufnrtotal
        Map<Integer,List<AppSceneCostSapZcorc>> levelZcorcs = new HashMap<>();
        for (AppSceneCostSapZcorc appSceneCostSapZcorc:zcorcs){
            if(appSceneCostSapZcorc.getPlayer().equals("0")){
                continue;
            }
            int level = appSceneCostSapZcorc.getLevel();
            if(levelZcorcs.containsKey(level)){
                List<AppSceneCostSapZcorc> items = levelZcorcs.get(level);
                items.add(appSceneCostSapZcorc);
                levelZcorcs.put(level,items);
            }else{
                List<AppSceneCostSapZcorc> items = new ArrayList<>();
                items.add(appSceneCostSapZcorc);
                levelZcorcs.put(level,items);
            }
        }
        for (int level:levelZcorcs.keySet()){
            List<AppSceneCostSapZcorc> zcorcList = levelZcorcs.get(level);
            for (AppSceneCostSapZcorc item:zcorcList){
                int index = item.getLayer().lastIndexOf("-");
                String lastcode = item.getLayer().substring(index+1,item.getLayer().length());
                String player = item.getPlayer();
                AppSceneCostSapZcorc pzcorc = numZcorc.get(player);
                AppSceneCostSapZcorc zcorc = numZcorc.get(item.getLayer());
                if(pzcorc==null){
                    logger.info("d");
                    continue;
                }
                if(lastcode.equals("0")){
                    zcorc.setPnum(pzcorc.getMatnrnum());
                    if(zcorc.getMenge()==null||zcorc.getPnum()==null||zcorc.getAufnrtotal()==null){
                        logger.info("d");
                        continue;
                    }
                    zcorc.setAufnrnum(zcorc.getMenge().multiply(zcorc.getPnum()).divide(zcorc.getAufnrtotal(),6,BigDecimal.ROUND_CEILING));
                }else{
                    zcorc.setPnum(pzcorc.getAufnrnum());
                    zcorc.setMatnrnum(zcorc.getPnum().multiply(zcorc.getUnmng()));
                }
                numZcorc.put(zcorc.getLayer(),zcorc);
            }
        }
        for (AppSceneCostSapZcorc item:zcorcs){
            AppSceneCostSapZcorc zcorc = numZcorc.get(item.getLayer());
            item.setAufnrnum(zcorc.getAufnrnum());
            item.setMatnrnum(zcorc.getMatnrnum());
            item.setPnum(zcorc.getPnum());
            //if(item.getMatnrnum()!=null&&(item.getMatnrnum().compareTo(BigDecimal.ZERO)==0)){
            //    item.setContent("可能存在替代料情况");
            //}
        }
    }

    public List<AppSceneCostSapZcorc> loadsapservice(String werks, String matnr, String posid, String ymonth) {
        HashMap<String, Object> hm = new HashMap<String, Object>();
        logger.info("loadsapservice " + werks + " " + matnr + " " + posid + " ");

        //String bmonth = getLastMonth(ymonth);
        String emonth = getNextMonth(ymonth);
        //if (ymonth.equals("")) {
        //    logger.info("can not find month " + matnr + " " + result.getPs_psp_pnr());
        //    continue;
        //}
        //String ymonth = result.getBudat_mkpf().substring(0, 6);
        String dateb = ymonth + "01";
        String datee = emonth + "01";
        String months = "06";

        Gson gson = new Gson();
        hm.put("werks", werks);
        hm.put("matnr", matnr);
        hm.put("pspnr", posid);
        hm.put("dateb", dateb);
        hm.put("datee", datee);
        hm.put("months", months);

        String url = env.getProperty("sap.service.url");
        String u = env.getProperty("sap.service.user");
        String p = env.getProperty("sap.service.password");

        List<AppSceneCostSapZcorc> versions = new ArrayList<>();


        SAPOrderServiceImpl sapOrderService = new SAPOrderServiceImpl();

        JSONObject jsonObject = sapOrderService.getOrderState12(hm, url, u, p);
        try {
            JSONArray items = jsonObject.getJSONObject("Body").getJSONObject("ZSAP_DSJ_005Response").getJSONObject("ES_OUTPUT").getJSONObject("DATA").getJSONObject("EX_TABLE").getJSONArray("item");
            Map<String,List<AppSceneCostSapZcorc>> mapSapZcorcResultList = new HashMap<>();
            if (items.size() > 0) {
                logger.info("load " + items.size() + " items");
                JSONObject firstObj = items.getJSONObject(0);
                String aufnr = firstObj.getString("AUFNR");
                //String ym = getYmonth(matnr, pspnr);
                String version = werks + "-" + matnr + "-" + aufnr + "-" + ymonth;
                for (int i = 0; i < items.size(); ++i) {
                    JSONObject newitem = ConvertTolowercase(items.getJSONObject(i));
                    AppSceneCostSapZcorc temp = new AppSceneCostSapZcorc();
                    Field[] field = temp.getClass().getDeclaredFields();
                    //SapZcorcResultKey key = new SapZcorcResultKey();
                    //Field[] field2 = key.getClass().getDeclaredFields();

                    JSONObject result = new JSONObject();
                    for (int j = 0; j < field.length; j++) {
                        String name = field[j].getName();
                        //if (name.equals("layer")) {
                        //    logger.info(name);
                        //}
                        if (newitem.get(name) != null) {
                            String type = field[j].getGenericType().toString();
                            if (type.equals("class java.lang.Double")) {
                                result.put(name, ConvertStringtoDouble(newitem.get(name).toString()));
                            } else if (type.equals("class java.math.BigDecimal")) {
                                result.put(name, ConvertStringtoDouble(newitem.get(name).toString()));
                            } else {
                                result.put(name, newitem.get(name));
                            }
                        }
                    }

                    AppSceneCostSapZcorc tmpSapZcorcResult = JSON.parseObject(result.toJSONString(), AppSceneCostSapZcorc.class);
                    if (tmpSapZcorcResult.getPlayer().equals("0")) {
                        aufnr = tmpSapZcorcResult.getAufnr();
                        version = werks + "-" + matnr + "-" + aufnr + "-" + ymonth;
                        versions.add(tmpSapZcorcResult);
                    }

                    tmpSapZcorcResult.setYmonth(ymonth);
                    tmpSapZcorcResult.setVersion(version);
                    if (tmpSapZcorcResult.getRkst001() != null && tmpSapZcorcResult.getRkst003() != null && tmpSapZcorcResult.getRkst0051() != null) {
                        double rkst000 = tmpSapZcorcResult.getRkst001().doubleValue() + tmpSapZcorcResult.getRkst003().doubleValue();
                        tmpSapZcorcResult.setRkst000(new BigDecimal(rkst000));
                        double rkstlabor = tmpSapZcorcResult.getRkst003().doubleValue() - tmpSapZcorcResult.getRkst0051().doubleValue();
                        tmpSapZcorcResult.setRkstlabor(new BigDecimal(rkstlabor));
                        if (tmpSapZcorcResult.getIdnrk() == null) {
                            tmpSapZcorcResult.setIdnrk("");
                        }
                        //tmpSapZcorcResultList.add(tmpSapZcorcResult);
                        if(mapSapZcorcResultList.containsKey(version)){
                            List<AppSceneCostSapZcorc> zcorcs=mapSapZcorcResultList.get(version);
                            zcorcs.add(tmpSapZcorcResult);
                            mapSapZcorcResultList.put(version,zcorcs);
                        }else{
                            List<AppSceneCostSapZcorc> zcorcs=new ArrayList<>();
                            zcorcs.add(tmpSapZcorcResult);
                            mapSapZcorcResultList.put(version,zcorcs);
                        }

                    } else {
                        logger.info("error:" + gson.toJson(tmpSapZcorcResult));
                    }
                }
                logger.info("Insert " + items.size() + " items "+mapSapZcorcResultList.keySet().size()+" aufnrs");
                for (String ver:mapSapZcorcResultList.keySet()){
                    List<AppSceneCostSapZcorc> zcorcs=mapSapZcorcResultList.get(ver);
                    FillNums(zcorcs,ymonth);
                    iAppSceneCostSapZcorcService.saveBatch(zcorcs);
                }
                //logger.info("7525 replaced ");
                //iAppSceneCostSapZcorcService.saveBatch(tmpSapZcorcResultList);
                return versions;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("error:" + e.getMessage());
            //logger.info("result :" + jsonObject.toJSONString());
        }

        return new ArrayList<>();
    }

    public int SetStatus(AppSceneCostMiningResult miningResult, String status) {
        miningResult.setStatus(status);
        logger.info(status);
        iAppSceneCostMiningResultService.updateById(miningResult);
        return 1;
        //return UpdateMiningResultBlobs(miningResult);
    }

    public int UpdateMiningResultBlobs(AppSceneCostMiningResult miningResultWithBLOBs) {
//        MiningResultExample example = new MiningResultExample();
//        MiningResultExample.Criteria criteria = example.createCriteria();
//        criteria.andMatnrEqualTo(miningResultWithBLOBs.getMatnr());
//        //criteria.andAufnrEqualTo(miningResultWithBLOBs.getAufnr());
//        criteria.andWbsEqualTo(miningResultWithBLOBs.getWbs());
//        criteria.andVersionEqualTo(miningResultWithBLOBs.getVersion());
//        List<MiningResult> results = miningResultMapper.selectByExample(example);
//        if (results.size() > 0) {
//            MiningResult miningResult = results.get(0);
//            miningResultWithBLOBs.setId(miningResult.getId());
//            miningResultWithBLOBs.setYmonth(miningResult.getYmonth());
//            miningResultMapper.updateByPrimaryKey(miningResultWithBLOBs);
//            return results.get(0).getId();
//        } else {
//            miningResultMapper.insert(miningResultWithBLOBs);
//            List<MiningResult> result2 = miningResultMapper.selectByExample(example);
//            if (result2.size() > 0) {
//                return result2.get(0).getId();
//            }
//        }
        return -1;
    }

    public void ClearCach() {
        rlayerMatnrMap.clear();
        layerAufnrMap.clear();
        tempSapZcorcList.clear();
        //auartMap.clear();
        afruMap.clear();
        //priceMap.clear();
        materialMap.clear();
        //resultindex=-1;
        zcorcAufnrMap.clear();
        zcorcMatnrMap.clear();
        miningReasonMap.clear();
        mapZtmmx004.clear();
        //motorSet.clear();
        //rlayers.clear();
        //materialDetailMap.clear();
    }

    public void getHourCost(HiveSapAfru hiveSapAfru, int resultindex) {
        try {
            Gson gson = new Gson();
            String ymonth = hiveSapAfru.budat;
            if (ymonth.length() > 6) {
                ymonth = ymonth.substring(0, 6);
            }
            String mapkey = hiveSapAfru.kostl + "." + ymonth;
            if (tempUniCost.containsKey(mapkey)) {
                hiveSapAfru.SetUnitCost(tempUniCost.get(mapkey));
            } else {
                AddMingLog(1, "无法找到实际小时费率:" + mapkey, resultindex);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void InitTempSapZcorc2(String matnr, String werks, String aufnr, String ymonth, int resultindex) {
        try {
            //SyncRedis(werks,ymonth);
            ClearCach();
            Gson gson = new Gson();
            String version = werks + "-" + matnr + "-" + aufnr + "-" + ymonth;
            QueryWrapper<AppSceneCostSapZcorc> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("version", version);
            queryWrapper.eq("ymonth", ymonth);
            List<AppSceneCostSapZcorc> appSceneCostSapZcorcs = iAppSceneCostSapZcorcService.list(queryWrapper);
            //String tablename = "sap_zcorc_result";
            //if (layer.indexOf("-") != -1) {
            //String sublayer = layer.substring(0, layer.length() - 1) + "%";
            // String sql2 = "SELECT * FROM  sap_zcorc_result  where layer like '" + sublayer + "' and ymonth='" + ymonth + "' and werks='" + werks + "'";
            //String sql2 = "select * from sap_zcorc_result where version='" + version + "' and ymonth='" + ymonth + "'";
            //Set<String> rlayers = new HashSet<>();
            Set<String> aufnrs = new HashSet<>();
            Set<String> matnrs = new HashSet<>();
            Set<String> costcenters = new HashSet<>();

            logger.info("Init first layer");
            HashSet<String> hashrlayers = new HashSet<String>();
            //List<Map<String, Object>> rows = mysqlJdbcTemplate.queryForList(sql2);
            for (AppSceneCostSapZcorc row : appSceneCostSapZcorcs) {
                //Map<String, Object> newrow = FormatMap(row, tablename);
                HiveSapZcorc hiveSapZcorc = gson.fromJson(gson.toJson(row), HiveSapZcorc.class);
                hiveSapZcorc.productname = hiveSapZcorc.maktx;
                if (tempSapZcorcList.containsKey(hiveSapZcorc.player)) {
                    List<HiveSapZcorc> hiveSapZcorcs = tempSapZcorcList.get(hiveSapZcorc.player);
                    hiveSapZcorcs.add(hiveSapZcorc);
                    tempSapZcorcList.put(hiveSapZcorc.player, hiveSapZcorcs);
                } else {
                    List<HiveSapZcorc> hiveSapZcorcs = new ArrayList<>();
                    hiveSapZcorcs.add(hiveSapZcorc);
                    tempSapZcorcList.put(hiveSapZcorc.player, hiveSapZcorcs);
                }
                //tempSapZcorcList.put(hiveSapZcorc.player, hiveSapZcorc);
                aufnrs.add(hiveSapZcorc.aufnr);
                matnrs.add(hiveSapZcorc.matnr);
                matnrs.add(hiveSapZcorc.idnrk);
                if (hiveSapZcorc.rlayer != null && hiveSapZcorc.rlayer.trim().length() > 0) {
                    hashrlayers.add(hiveSapZcorc.rlayer);
                } else {
                    hashrlayers.add(hiveSapZcorc.layer);
                }
            }
            rlayers.addAll(hashrlayers);


            logger.info("init hour rate");
            if (true) {
                //QueryWrapper<AppSceneCostSapHourRate> queryWrapper1=new QueryWrapper<>();
                List<AppSceneCostSapHourRate> appSceneCostSapHourRates = iAppSceneCostSapHourRateService.list();
                //String sql = "SELECT * FROM  zcorc.Calculation_MonthlyUnitTimeCost";
                //List<Map<String, Object>> rows2 = hiveJdbcTemplate.queryForList(sql);
                //String sql = "SELECT * FROM  Calculation_MonthlyUnitTimeCost";
                //List<Map<String, Object>> rows2 = mysqlJdbcTemplate.queryForList(sql);
                for (AppSceneCostSapHourRate row : appSceneCostSapHourRates) {
                    //Map<String, Object> newrow = FormatMap(row, tablename);
                    UnitCost unitCost = new UnitCost();
                    double minute = 60;
                    unitCost.rgfv = row.getRgfv().doubleValue() / minute;
                    unitCost.sbfv = row.getSbfv().doubleValue() / minute;
                    unitCost.rdfv = row.getRdfv().doubleValue() / minute;
                    unitCost.flfv = row.getFlfv().doubleValue() / minute;
                    unitCost.qtfv = row.getQtfv().doubleValue() / minute;

                    String code = row.getCenterCode();
                    String month = row.getYm();
                    tempUniCost.put(code + "." + month, unitCost);
                }
            }

            logger.info("Init afru");
            if (aufnrs.size() > 0) {
                // String sql = "SELECT * FROM  sap_afru  where werks='" + werks + "'";
                //sql += " and (";
                //String sql = "SELECT * FROM  zcorc.sap_afru  where (";
//                String sql = "SELECT * FROM  sap_afru  where (";
//                int index = 0;
//                for (String aufnr : aufnrs) {
//                    if (index != 0) {
//                        sql += " or ";
//                    }
//                    index++;
//                    sql += "aufnr = '" + aufnr + "'";
//                }
//                sql += ")";
                QueryWrapper<AppSceneCostSapAfru> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.in("aufnr", aufnrs);
                List<AppSceneCostSapAfru> appSceneCostSapAfrus = iAppSceneCostSapAfruService.list(queryWrapper1);
                //List<Map<String, Object>> rows2 = hiveJdbcTemplate.queryForList(sql);
                //List<Map<String, Object>> rows2 = mysqlJdbcTemplate.queryForList(sql);
                for (AppSceneCostSapAfru row : appSceneCostSapAfrus) {
                    //Map<String, Object> newrow = FormatMap(row, tablename);
                    HiveSapAfru hiveSapAfru = gson.fromJson(gson.toJson(row), HiveSapAfru.class);
                    getHourCost(hiveSapAfru, resultindex);
                    String anfnr = hiveSapAfru.aufnr;

                    if (afruMap.containsKey(anfnr)) {
                        afruMap.get(anfnr).add(hiveSapAfru);
                    } else {
                        List<HiveSapAfru> list = new ArrayList<>();
                        list.add(hiveSapAfru);
                        afruMap.put(anfnr, list);
                    }
                }
            }

            List<AppSceneCostSapZtmmx004> sapZtmmx004s=iAppSceneCostSapZtmmx004Service.list();
            for (AppSceneCostSapZtmmx004 ztmmx004:sapZtmmx004s){
                if(mapZtmmx004.containsKey(ztmmx004.getMatnr())){
                    List<AppSceneCostSapZtmmx004> data = mapZtmmx004.get(ztmmx004.getMatnr());
                    data.add(ztmmx004);
                    mapZtmmx004.put(ztmmx004.getMatnr(),data);
                }else{
                    List<AppSceneCostSapZtmmx004> data = new ArrayList<>();
                    data.add(ztmmx004);
                    mapZtmmx004.put(ztmmx004.getMatnr(),data);
                }
            }

//            logger.info("Init price");
//            if (matnrs.size() > 0) {
//                String sql = "SELECT * FROM  srm_price  where approve_status='审批通过'";
//                sql += " and (";
//                int index = 0;
//                for (String matnr : matnrs) {
//                    if (index != 0) {
//                        sql += " or ";
//                    }
//                    index++;
//                    sql += "material_code = '" + matnr + "'";
//                }
//                sql += ")";
////                List<Map<String, Object>> rows2 = hiveJdbcTemplate.queryForList(sql);
////                for (Map<String, Object> row : rows2) {
////                    //0-1-0
////                    Map<String, Object> newrow2 = FormatMap(row, tablename);
////                    SrmPrice srmPrice = gson.fromJson(gson.toJson(newrow2), SrmPrice.class);
////                    //srmPriceList.add(srmPrice);
////                    if (priceMap.containsKey(srmPrice.material_code)) {
////                        priceMap.get(srmPrice.material_code).add(srmPrice);
////                    } else {
////                        List<SrmPrice> list = new ArrayList<>();
////                        list.add(srmPrice);
////                        priceMap.put(srmPrice.material_code, list);
////                    }
////                }
//            }

            logger.info("init material");
            if (matnrs.size() > 0) {
                List<String> list = new ArrayList<>();
                for (String matnr1 : matnrs) {
                    list.add(matnr1);
                }
                QueryWrapper<AppSceneCostMaterial> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.in("material_number", list);
                queryWrapper1.eq("factory", werks);
                //MaterialExample example = new MaterialExample();
                //MaterialExample.Criteria criteria = example.createCriteria();
                //criteria.andMaterialNumberIn(list);
                //criteria.andFactoryEqualTo(werks);
                List<AppSceneCostMaterial> materialList = iAppSceneCostMaterialService.list(queryWrapper1);
                for (AppSceneCostMaterial material : materialList) {
                    materialMap.put(material.getMaterialNumber(), material);
                }

                //for (HiveSapZcorc hiveSapZcorc:tempSapZcorcList.values()){
                //    hiveSapZcorc.productname = hiveSapZcorc.maktx;
                //if(materialMap.containsKey(hiveSapZcorc.matnr)){
                //    hiveSapZcorc.productname=materialMap.get(hiveSapZcorc.matnr).getProductName();
                // }
                // }

            }

//            logger.info("init motor");
//            if (matnrs.size() > 0) {
//                List<DictMotor> materialList = dictMotorMapper.selectByExample(new DictMotorExample());
//                for (DictMotor material : materialList) {
//                    motorSet.add(material.getMatnr());
//                }
//
//                //for (HiveSapZcorc hiveSapZcorc:tempSapZcorcList.values()){
//                //    hiveSapZcorc.productname = hiveSapZcorc.maktx;
//                //if(materialMap.containsKey(hiveSapZcorc.matnr)){
//                //    hiveSapZcorc.productname=materialMap.get(hiveSapZcorc.matnr).getProductName();
//                // }
//                // }
//
//            }

            // }
            //String sql="select * from "+tablename+" where werks"
        } catch (Exception e) {
            throw e;
        }
    }

    public void Init(VersionTmp versionTmp) {
        if (versionTmp.totalHourRate.size() == 0) {
            QueryWrapper<AppSceneCostHourRate> queryWrapper = new QueryWrapper<>();
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);
            queryWrapper.eq("year", year);
            versionTmp.totalHourRate = iAppSceneCostHourRateService.list(queryWrapper);
            //HourRateExample example = new HourRateExample();
            //Calendar calendar = Calendar.getInstance();
            //int year = calendar.get(Calendar.YEAR);
            //HourRateExample.Criteria criteria = example.createCriteria();
            //criteria.andYearEqualTo(String.valueOf(year));
            //versionTmp.totalHourRate = hourRateMapper.selectByExample(example);
        }
//        if (versionTmp.innerSupplierMap.size() == 0) {
//            InnerSupplierExample example = new InnerSupplierExample();
//            List<InnerSupplier> innerSupplierList = innerSupplierMapper.selectByExample(example);
//            for (InnerSupplier innerSupplier : innerSupplierList) {
//                if (versionTmp.innerSupplierMap.containsKey(innerSupplier.getSupplierCode())) {
//                    List<InnerSupplier> innerSuppliers = versionTmp.innerSupplierMap.get(innerSupplier.getSupplierCode());
//                    innerSuppliers.add(innerSupplier);
//                    versionTmp.innerSupplierMap.put(innerSupplier.getSupplierCode(), innerSuppliers);
//                } else {
//                    List<InnerSupplier> innerSuppliers = new ArrayList<>();
//                    innerSuppliers.add(innerSupplier);
//                    versionTmp.innerSupplierMap.put(innerSupplier.getSupplierCode(), innerSuppliers);
//                }
//                //innerSupplierMap.put(innerSupplier.getSupplierCode(), innerSupplier);
//            }
//        }
    }

    public void InitBom(String matnr, String werks, String proversion, VersionTmp versionTmp) {
        try {
            Set<String> allmatnrs = new HashSet<>();
            allmatnrs.add(matnr);
            // String version="";

            Set<String> matnrSet = new HashSet<>();
            matnrSet.add(matnr);
            logger.info("Init bom");
            while (!matnrSet.isEmpty()) {
                List<String> list = new ArrayList<>();
                for (String item : matnrSet) {
                    if (!versionTmp.bomMap.containsKey(item)) {
                        list.add(item);
                    }
                }
                if (list.size() == 0) {
                    break;
                }
                QueryWrapper<AppSceneCostBomRelevancy> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("matnr", list);
                queryWrapper.eq("werks", werks);
                List<AppSceneCostBomRelevancy> bomRelevancyList = iAppSceneCostBomRelevancyService.list(queryWrapper);
//                BomRelevancyExample example = new BomRelevancyExample();
//                BomRelevancyExample.Criteria criteria = example.createCriteria();
//                criteria.andMatnrIn(list);
//                criteria.andWerksEqualTo(werks);
//                List<BomRelevancy> bomRelevancyList = bomRelevancyMapper.selectByExample(example);
                matnrSet.clear();
                for (AppSceneCostBomRelevancy bomRelevancy : bomRelevancyList) {
                    //if(bomRelevancy.getMatnr().equals(matnr)&&version.equals("")){
                    //    version=bomRelevancy.getVersionNumber();
                    //}
                    if (!versionTmp.bomMap.containsKey(bomRelevancy.getMatnr())) {
                        List<AppSceneCostBomRelevancy> bomRelevancyList1 = new ArrayList<>();
                        bomRelevancyList1.add(bomRelevancy);
                        versionTmp.bomMap.put(bomRelevancy.getMatnr(), bomRelevancyList1);
                    } else {
                        versionTmp.bomMap.get(bomRelevancy.getMatnr()).add(bomRelevancy);
                    }
                    matnrSet.add(bomRelevancy.getIdnrk());
                    allmatnrs.add(bomRelevancy.getIdnrk());
                }
            }

            List<String> listmatnrs = new ArrayList<>();
            for (String item : allmatnrs) {
                listmatnrs.add(item);
            }
            listmatnrs.add(matnr);

//            logger.info("Init ProductProcessMaintenance");
//            if (true) {
//                SapProcessRouteExample example = new SapProcessRouteExample();
//                SapProcessRouteExample.Criteria criteria = example.createCriteria();
//                criteria.andMatnrIn(listmatnrs);
//                criteria.andWerksEqualTo(werks);
//                //criteria.andVersionNumberEqualTo(version);
//                List<SapProcessRoute> productProcessMaintenanceList = sapProcessRouteMapper.selectByExample(example);
//                for (SapProcessRoute productProcessMaintenance : productProcessMaintenanceList) {
//                    if (!versionTmp.productMap.containsKey(productProcessMaintenance.getMatnr())) {
//                        List<SapProcessRoute> bomRelevancyList1 = new ArrayList<>();
//                        bomRelevancyList1.add(productProcessMaintenance);
//                        versionTmp.productMap.put(productProcessMaintenance.getMatnr(), bomRelevancyList1);
//                    } else {
//                        versionTmp.productMap.get(productProcessMaintenance.getMatnr()).add(productProcessMaintenance);
//                    }
//                }
//            }


//            logger.info("Init taxed");
//            if (true) {
//                List<Taxes> taxes = taxesMapper.selectByExample(new TaxesExample());
//                for (Taxes taxes1 : taxes) {
//                    versionTmp.taxesMap.put(taxes1.getMatnr(), taxes1);
//                }
//            }

            List<String> mklist = new ArrayList<>();

            logger.info("Init material");
            if (true) {
                QueryWrapper<AppSceneCostMaterial> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("material_number", listmatnrs);
                queryWrapper.eq("factory", werks);
                List<AppSceneCostMaterial> materialList = iAppSceneCostMaterialService.list(queryWrapper);
//                MaterialExample example = new MaterialExample();
//                MaterialExample.Criteria criteria = example.createCriteria();
//                criteria.andMaterialNumberIn(listmatnrs);
//                criteria.andFactoryEqualTo(werks);
//                List<Material> materialList = materialMapper.selectByExample(example);
                for (AppSceneCostMaterial material : materialList) {
                    if (!versionTmp.materialMap.containsKey(material.getMaterialNumber())) {
                        versionTmp.materialMap.put(material.getMaterialNumber(), material);
                        if (material.getOldMaterialGroup() != null && material.getOldMaterialGroup().equals("100")) {
                            mklist.add(material.getMaterialNumber());
                        }
                    }
                }
                //criteria.andVersionNumberEqualTo(version);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void loadProductProcess(StandardMatnr standardMatnr, List<AppSceneCostStandardProductprocess> standardProductprocesses) {
        try {
            logger.info("loadProductProcess " + standardMatnr.matnr);
            standardMatnr.productProcessMaintenanceList = new ArrayList<>();
            for (AppSceneCostStandardProductprocess standardProductprocess : standardProductprocesses) {
                if (standardProductprocess.getMainPartNumber().equals(standardMatnr.matnr) &&
                        standardProductprocess.getFactory().equals(standardMatnr.werks) &&
                        standardProductprocess.getVersionNumber().equals(standardMatnr.version)) {
                    standardMatnr.productProcessMaintenanceList.add(standardProductprocess);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void loadChildBom(StandardMatnr standardMatnr, List<AppSceneCostStandardResult> standardResults, List<AppSceneCostStandardBom> standardBoms, List<AppSceneCostStandardProductprocess> standardProductprocesses) {
        try {
            int index = 0;
            Gson gson = new Gson();

            for (AppSceneCostStandardResult standardResult : standardResults) {
                if (!standardResult.getParentMatnr().equals(standardMatnr.matnr))
                    continue;
                String layer = standardResult.getLayer();
                //if (layer.length() < standardMatnr.layer.length() + 1)
                //    continue;
                //if (!layer.substring(0, standardMatnr.layer.length()).equals(standardMatnr.layer))
                //    continue;
                if (!standardResult.getPlayer().equals(standardMatnr.layer)) {
                    continue;
                }
                index++;
                if(standardResult.getMaterialNumber().equals("02020010001800")){
                    logger.info("02020010001800");
                }
                //logger.info(depth + ":" + standardMatnr.matnr + ":" + standardMatnr.layer + "-" + index + ":" + index + "/" + standardBomArrayList.size());

                StandardMatnr standardMatnr1 = new StandardMatnr();
                standardMatnr1.matnr = standardResult.getMaterialNumber();
                standardMatnr1.werks = standardMatnr.werks;
                standardMatnr1.version = standardMatnr.version;
                standardMatnr1.layer = standardResult.getLayer();
                standardMatnr1.standardResult = standardResult;
                standardMatnr1.GenerateStandardCalculate();
                for (AppSceneCostStandardBom standardBom : standardBoms) {
                    if (standardMatnr1.matnr.equals(standardBom.getIdnrk()) && standardMatnr.matnr.equals(standardBom.getMatnr())) {
                        standardMatnr1.standardBom = gson.fromJson(gson.toJson(standardBom), AppSceneCostStandardBom.class);
                        double menge = standardResult.getMenge().doubleValue();
                        standardMatnr1.standardBom.setMenge(new BigDecimal(menge));
                    }
                }
                loadProductProcess(standardMatnr1, standardProductprocesses);
                loadChildBom(standardMatnr1, standardResults, standardBoms, standardProductprocesses);
                standardMatnr.childs.add(standardMatnr1);
            }
        } catch (KNException ex) {
            throw ex;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public StandardMatnr loadStandardCost2(String matnr, String version, String werks) {
        try {
            StandardMatnr standardMatnr = new StandardMatnr();
            standardMatnr.matnr = matnr;
            standardMatnr.version = version;
            //standardMatnr.setBatch(batch);
            standardMatnr.werks = werks;
            standardMatnr.layer = "0";

            VersionTmp versionTmp = new VersionTmp();
            Init(versionTmp);
            InitBom(matnr, werks, version, versionTmp);
            versionTmpMap.put(version, versionTmp);

            QueryWrapper<AppSceneCostStandardResult> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("version_number", standardMatnr.version);
            queryWrapper.eq("factory", werks);
            //StandardResultExample example1 = new StandardResultExample();
            //StandardResultExample.Criteria criteria1 = example1.createCriteria();
            //criteria1.andMaterialNumberEqualTo(standardMatnr.matnr);
            //criteria1.andVersionNumberEqualTo(standardMatnr.version);
            //criteria1.andFactoryEqualTo(werks);
            List<AppSceneCostStandardResult> standardResults = iAppSceneCostStandardResultService.list(queryWrapper);
            boolean bFind = false;
            if (standardResults.size() > 0) {
                for (AppSceneCostStandardResult standardResult : standardResults) {
                    if (standardResult.getLayer().equals("0") && standardResult.getMaterialNumber().equals(matnr)) {
                        standardMatnr.standardResult = standardResult;
                        QueryWrapper<AppSceneCostMaterial> queryWrapper1 = new QueryWrapper<>();
                        queryWrapper1.eq("material_number", matnr);
                        queryWrapper1.eq("factory", werks);
                        List<AppSceneCostMaterial> materialList = iAppSceneCostMaterialService.list(queryWrapper1);
                        //MaterialExample example = new MaterialExample();
                        //MaterialExample.Criteria criteria = example.createCriteria();
                        //criteria.andMaterialNumberEqualTo(matnr);
                        //criteria.andFactoryEqualTo(werks);
                        //List<Material> materialList = materialMapper.selectByExample(example);
                        if (materialList.size() > 0) {
                            AppSceneCostMaterial material = materialList.get(0);
                            standardMatnr.standardBom.setProductName(material.getProductName());
                        }
                        standardMatnr.GenerateStandardCalculate();
                        bFind = true;
                        break;
                    }
                }
            }
            if (bFind) {
                //StandardBomExample example2 = new StandardBomExample();
                //StandardBomExample.Criteria criteria2 = example2.createCriteria();
                //criteria2.andVersionNumberEqualTo(standardMatnr.version);
                //List<StandardBom> standardBomArrayList = standardBomMapper.selectByExample(example2);
                QueryWrapper<AppSceneCostStandardBom> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("version_number", standardMatnr.version);
                List<AppSceneCostStandardBom> standardBomArrayList = iAppSceneCostStandardBomService.list(queryWrapper2);


                QueryWrapper<AppSceneCostStandardProductprocess> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("factory", standardMatnr.werks);
                queryWrapper1.eq("version_number", standardMatnr.version);

                //StandardProductprocessExample example = new StandardProductprocessExample();
                //StandardProductprocessExample.Criteria criteria = example.createCriteria();
                //criteria.andFactoryEqualTo(standardMatnr.werks);
                //criteria.andMainPartNumberEqualTo(standardMatnr.matnr);
                //criteria.andVersionNumberEqualTo(standardMatnr.version);
                List<AppSceneCostStandardProductprocess> productProcessMaintenanceList = iAppSceneCostStandardProductprocessService.list(queryWrapper1);
                for (AppSceneCostStandardProductprocess productprocess:productProcessMaintenanceList){
                    productprocess.setPrepareHour(productprocess.getPrepareHour().divide(new BigDecimal(60),BigDecimal.ROUND_CEILING));
                    productprocess.setLaborHour(productprocess.getLaborHour().divide(new BigDecimal(60),BigDecimal.ROUND_CEILING));
                    productprocess.setMachineHour(productprocess.getMachineHour().divide(new BigDecimal(60),BigDecimal.ROUND_CEILING));
                    productprocess.setBurningHour(productprocess.getBurningHour().divide(new BigDecimal(60),BigDecimal.ROUND_CEILING));
                    productprocess.setAuxiliaryHour(productprocess.getAuxiliaryHour().divide(new BigDecimal(60),BigDecimal.ROUND_CEILING));
                    productprocess.setOtherHour(productprocess.getOtherHour().divide(new BigDecimal(60),BigDecimal.ROUND_CEILING));
                }


                loadChildBom(standardMatnr, standardResults, standardBomArrayList, productProcessMaintenanceList);
                loadProductProcess(standardMatnr, productProcessMaintenanceList);
            }

            //loadChildBom(standardMatnr);
            //loadProductProcess(standardMatnr);
            //standardMatnr.GenerateStandardCalculate();
            return standardMatnr;
        } catch (KNException ex) {
            throw ex;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void CheckAfru(ZcorcAufnr nodeAufnr, int resultindex) {
        if (nodeAufnr.hiveSapZcorc.rkst301 > 0) {
            double total301 = 0;
            double total302 = 0;
            double total303 = 0;
            double total304 = 0;
            for (HiveSapAfru hiveSapAfru : nodeAufnr.hiveSapAfruList) {
                total301 += hiveSapAfru.ism02 * hiveSapAfru.unitCost.sbfv;
                total302 += hiveSapAfru.ism04 * hiveSapAfru.unitCost.rdfv;
                total303 += hiveSapAfru.ism05 * hiveSapAfru.unitCost.flfv;
                total304 += hiveSapAfru.ism06 * hiveSapAfru.unitCost.qtfv;
            }
            if (nodeAufnr.hiveSapAfruList.size() == 0) {
                AddMingLog(1, nodeAufnr.hiveSapZcorc.aufnr + ":" + nodeAufnr.hiveSapZcorc.layer + " 未找到报工", resultindex);
                return;
            }
            double diff301 = total301 - nodeAufnr.hiveSapZcorc.rkst301;
            if (Math.abs(total301 - nodeAufnr.hiveSapZcorc.rkst301) > 1) {
                //logger.info(nodeAufnr.hiveSapZcorc.layer + " 本阶设备费用不等:"+(total301 - nodeAufnr.hiveSapZcorc.rkst301));
                AddMingLog(1, nodeAufnr.hiveSapZcorc.aufnr + ":" + nodeAufnr.hiveSapZcorc.layer + " 本阶设备费用不等:" + diff301, resultindex);
            }
            double diff302 = total302 - nodeAufnr.hiveSapZcorc.rkst302;
            if (Math.abs(total302 - nodeAufnr.hiveSapZcorc.rkst302) > 1) {
                //logger.info(nodeAufnr.hiveSapZcorc.layer + " 本阶燃动费用不等:"+(total302 - nodeAufnr.hiveSapZcorc.rkst302));
                AddMingLog(1, nodeAufnr.hiveSapZcorc.aufnr + ":" + nodeAufnr.hiveSapZcorc.layer + " 本阶燃动费用不等:" + diff302, resultindex);
            }
            double diff303 = total303 - nodeAufnr.hiveSapZcorc.rkst303;
            if (Math.abs(total303 - nodeAufnr.hiveSapZcorc.rkst303) > 1) {
                //logger.info(nodeAufnr.hiveSapZcorc.layer + " 本阶辅料费用不等:"+(total303 - nodeAufnr.hiveSapZcorc.rkst303));
                AddMingLog(1, nodeAufnr.hiveSapZcorc.aufnr + ":" + nodeAufnr.hiveSapZcorc.layer + " 本阶辅料费用不等:" + diff303, resultindex);
            }
            double diff304 = total304 - nodeAufnr.hiveSapZcorc.rkst304;
            if (Math.abs(total304 - nodeAufnr.hiveSapZcorc.rkst304) > 1) {
                //logger.info(nodeAufnr.hiveSapZcorc.layer + " 本阶其他费用不等:"+(total304 - nodeAufnr.hiveSapZcorc.rkst304));
                AddMingLog(1, nodeAufnr.hiveSapZcorc.aufnr + ":" + nodeAufnr.hiveSapZcorc.layer + " 本阶其他费用不等:" + diff304, resultindex);
            }
        }
    }

    public void getHiveProcess(ZcorcAufnr nodeAufnr, int resultindex, boolean bCheck) {
        try {
            if (nodeAufnr.hiveSapZcorc.rkstlabor <= 0) {
                return;
            }
            Gson gson = new Gson();
            List<HiveSapAfru> hiveSapAfruList = afruMap.get(nodeAufnr.hiveSapZcorc.aufnr);
            if (nodeAufnr.hiveSapZcorc.aufnr != null && nodeAufnr.hiveSapZcorc.aufnr.equals("000100899757")) {
                logger.info("Debug");
            }
            if (hiveSapAfruList != null) {
                for (HiveSapAfru item : hiveSapAfruList) {
                    HiveSapAfru hiveSapAfru = gson.fromJson(gson.toJson(item), HiveSapAfru.class);
                    String month = hiveSapAfru.budat.substring(0, 6);
                    //如果同一个工单下同样的工序编号和报工日期属于同一个月，则合并工序的时间
                    boolean bExist = false;
                    for (HiveSapAfru hiveSapAfru1 : nodeAufnr.hiveSapAfruList) {
                        String month2 = hiveSapAfru1.budat.substring(0, 6);
                        if (hiveSapAfru1.rueck.equals(hiveSapAfru.rueck) && month2.equals(month)) {
                            hiveSapAfru1.AddArfu(hiveSapAfru);
                            bExist = true;
                            break;
                        }
                    }
                    if (!bExist) {
                        nodeAufnr.hiveSapAfruList.add(hiveSapAfru);
                    }
                }
            }
            if (bCheck) {
                CheckAfru(nodeAufnr, resultindex);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void CalculateStagePrice(ZcorcMatnr nodeMatnr) {
        double totalnum = 0;
        double totalmaterialprice = 0;
        for (String layer : nodeMatnr.childs) {
            ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(layer);
            totalnum += nodeAufnr.hiveSapZcorc.menge;//
            for (String layer1 : nodeAufnr.childs) {
                ZcorcMatnr nodeMatnr1 = zcorcMatnrMap.get(layer1);
                totalmaterialprice += nodeMatnr1.hiveSapZcorc.rkst001;
            }
        }
        //计算工单在上阶物料中的取料比例
        if (totalnum > 0) {
            for (String layer : nodeMatnr.childs) {
                ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(layer);
                nodeAufnr.rate = nodeAufnr.hiveSapZcorc.menge / totalnum;
            }
        }


        if (totalnum > 0) {
            double singleprice = totalmaterialprice / totalnum;
            String layer = nodeMatnr.hiveSapZcorc.layer;
            if (layer.equals("0-6273-6")) {
                singleprice = totalmaterialprice / totalnum;
            }
            if (nodeMatnr.hiveSapZcorc.unmng > 0) {
                nodeMatnr.stageprice = nodeMatnr.hiveSapZcorc.kst001 / nodeMatnr.hiveSapZcorc.unmng - singleprice;
            }
        }
    }

    public int getChildNodeAufnr(ZcorcMatnr nodeMatnr, List<String> pmatnrs, String strindex, int depth, int resultindex, int count) {
        if (nodeMatnr.hiveSapZcorc != null) {
            Gson gson = new Gson();
            //logger.info(depth+" NodeAufnr " + nodeMatnr.hiveSapZcorc.layer);
            String parentlayer = nodeMatnr.hiveSapZcorc.layer;
            String idnrk = nodeMatnr.hiveSapZcorc.idnrk;
            //String pmatnr=nodeMatnr.hiveSapZcorc.matnr;
            String ymonth = nodeMatnr.hiveSapZcorc.ymonth;
            String werks = nodeMatnr.hiveSapZcorc.werks;
            if (nodeMatnr.hiveSapZcorc.rlayer != null) {
                if (!nodeMatnr.hiveSapZcorc.rlayer.trim().equals("")) {
                    parentlayer = nodeMatnr.hiveSapZcorc.rlayer;
                }
            }

            List<HiveSapZcorc> childs = new ArrayList<>();
            List<HiveSapZcorc> hiveSapZcorcList = tempSapZcorcList.get(parentlayer);
            if (hiveSapZcorcList == null) {
                return count;
            }
            //logger.info("getChildNodeAufnr " + parentlayer);
            for (HiveSapZcorc hiveSapZcorc : hiveSapZcorcList) {
                //if (hiveSapZcorc.ymonth.equals(ymonth) &&
                //        hiveSapZcorc.matnr.equals(idnrk) &&
                //hiveSapZcorc.werks.equals(werks)&&hiveSapZcorc.aufnr!=null&&(!hiveSapZcorc.aufnr.equals(" "))) {
                //         hiveSapZcorc.werks.equals(werks)) {
                String layer = hiveSapZcorc.layer;
                if (layer.equals("0-1525-27-1-83-2-0")) {
                    logger.info("test");
                }
                //if (layer.length() > parentlayer.length() &&
                //        layer.substring(0, parentlayer.length()).equals(parentlayer)) {
                //String endsub = layer.substring(parentlayer.length(), layer.length());
                //if (endsub.length() > 3 && endsub.substring(endsub.length() - 2, endsub.length()).equals("-0") && endsub.substring(0, 1).equals("-")) {
                // String midsub = endsub.substring(1, endsub.length() - 2);
                // if (midsub.indexOf("-") == -1) {
                HiveSapZcorc hiveSapZcorc1 = new HiveSapZcorc();
                BeanUtils.copyProperties(hiveSapZcorc, hiveSapZcorc1);
                //HiveSapZcorc hiveSapZcorc1 = gson.fromJson(gson.toJson(hiveSapZcorc), HiveSapZcorc.class);
                hiveSapZcorc1.ReplaceActual();
                childs.add(hiveSapZcorc1);

//                                NodeAufnr nodeAufnr = new NodeAufnr();
//                                nodeAufnr.hiveSapZcorc = hiveSapZcorc1;
//                                FillNodeAufnrAuart(nodeAufnr.hiveSapZcorc);
//                                getHiveProcess(nodeAufnr);
//                                getChildZcorcMatnr(nodeAufnr,pmatnrs,depth+1);
//                                nodeMatnr.childs.add(nodeAufnr);
//                                CalculateStagePrice(nodeMatnr);
                //  }
                //}
                //}
                //}
            }

            int index = 0;
            for (HiveSapZcorc hiveSapZcorc1 : childs) {
                index++;
                count++;
                String layer = hiveSapZcorc1.layer;
                if (zcorcAufnrMap.containsKey(layer)) {
                    nodeMatnr.childs.add(layer);
                    CalculateStagePrice(nodeMatnr);
                    continue;
                }
                String subindex = strindex + "[" + index + "/" + childs.size() + "]";
                logger.info("Count:" + count + " Depth:" + depth + ":" + subindex + ":" + idnrk + ":Layer:" + parentlayer);
                ZcorcAufnr nodeAufnr = new ZcorcAufnr();
                nodeAufnr.hiveSapZcorc = hiveSapZcorc1;
                //FillNodeAufnrAuart(nodeAufnr.hiveSapZcorc);
                getHiveProcess(nodeAufnr, resultindex, false);
                count = getChildNodeMatnr(nodeAufnr, pmatnrs, subindex, depth + 1, resultindex, count);
                //nodeMatnr.childs.add(nodeAufnr);
                zcorcAufnrMap.put(layer, nodeAufnr);
                //}
                nodeMatnr.childs.add(layer);
                if (count == 94) {
                    logger.info("Debug");
                }
                CalculateStagePrice(nodeMatnr);
            }
        }
        return count;
    }

    public int getChildNodeMatnr(ZcorcAufnr nodeAufnr, List<String> pmatnrs, String strindex, int depth, int resultindex, int count) {
        if (nodeAufnr.hiveSapZcorc != null) {
            //count++;
            //logger.info(depth+" NodeMatnr " + nodeAufnr.hiveSapZcorc.layer);
            String parentlayer = nodeAufnr.hiveSapZcorc.layer;
            if (parentlayer.equals("0-1-6-1-87-1-0")) {
                logger.info("Debug");
            }
            //parentlayer = parentlayer.substring(0, parentlayer.length() - 1) + "%";
            int length = parentlayer.length();
            String idnrk = nodeAufnr.hiveSapZcorc.idnrk;
            String ymonth = nodeAufnr.hiveSapZcorc.ymonth;
            String werks = nodeAufnr.hiveSapZcorc.werks;

            List<HiveSapZcorc> childs = new ArrayList<>();
            Gson gson = new Gson();
            List<HiveSapZcorc> hiveSapZcorcList = tempSapZcorcList.get(parentlayer);
            if (hiveSapZcorcList != null) {

                for (HiveSapZcorc hiveSapZcorc : hiveSapZcorcList) {
                    if (hiveSapZcorc.idnrk == null) {
                        hiveSapZcorc.idnrk = "";
                    }
                    //if (hiveSapZcorc.ymonth.equals(ymonth) &&
                    //        hiveSapZcorc.matnr.equals(idnrk) &&
                    //         !hiveSapZcorc.idnrk.equals(idnrk) &&
                    //         hiveSapZcorc.werks.equals(werks)) {
                    String layer = hiveSapZcorc.layer;
                    //if (layer.length() > parentlayer.length() - 1) {
                    //    if (layer.substring(0, parentlayer.length() - 1).equals(parentlayer.substring(0, parentlayer.length() - 1))) {
                    //index++;
                    //List<String> npmatnr=new ArrayList<>();
                    //npmatnr.addAll(pmatnrs);
                    HiveSapZcorc hiveSapZcorc1 = new HiveSapZcorc();
                    BeanUtils.copyProperties(hiveSapZcorc, hiveSapZcorc1);
                    //HiveSapZcorc hiveSapZcorc1 = gson.fromJson(gson.toJson(hiveSapZcorc), HiveSapZcorc.class);
                    hiveSapZcorc1.ReplaceActual();
                    childs.add(hiveSapZcorc1);
//                            NodeMatnr nodeMatnr = new NodeMatnr();
//                            nodeMatnr.hiveSapZcorc = hiveSapZcorc1;
//                            logger.info("Depth:"+depth+":Layer:"+nodeAufnr.hiveSapZcorc.layer+":index:"+index+" ("+idnrk+"-"+hiveSapZcorc1.idnrk+")");
//                            for (String pmatnr:npmatnr){
//                                if(pmatnr.equals(hiveSapZcorc1.idnrk)){
//                                    throw new KNException(0,"物料号循环引用:"+hiveSapZcorc1.idnrk+" "+hiveSapZcorc1.layer);
//                                }
//                            }
//                            npmatnr.add(hiveSapZcorc1.idnrk);
//                            getChildNodeAufnr(nodeMatnr,npmatnr,depth+1);
//                            nodeAufnr.childs.add(nodeMatnr);
                    //    }
                    // }
                    //}
                }
            }

            int index = 0;
            for (HiveSapZcorc hiveSapZcorc1 : childs) {
                index++;
                count++;
                String layer = hiveSapZcorc1.layer;
                //if (hiveSapZcorc1.rlayer != null) {
                //    layer = hiveSapZcorc1.rlayer;
                //}
                if (zcorcMatnrMap.containsKey(layer)) {
                    nodeAufnr.childs.add(layer);
                    continue;
                }
                List<String> npmatnr = new ArrayList<>();
                npmatnr.addAll(pmatnrs);
                ZcorcMatnr nodeMatnr = new ZcorcMatnr();
                nodeMatnr.hiveSapZcorc = hiveSapZcorc1;
                String subindex = strindex + "[" + index + "/" + childs.size() + "]";
                logger.info("Count:" + count + " Depth:" + depth + ":" + subindex + ":Layer:" + nodeAufnr.hiveSapZcorc.layer + " (" + idnrk + "-" + hiveSapZcorc1.idnrk + ")");
                int pindex = 0;
                for (String pmatnr : npmatnr) {
                    pindex++;
                    if (pmatnr.equals(hiveSapZcorc1.idnrk)) {
                        if (pindex != npmatnr.size()) {
                            throw new KNException(0, "物料号循环引用:" + hiveSapZcorc1.idnrk + " " + hiveSapZcorc1.layer);
                        }
                    }
                }
                npmatnr.add(hiveSapZcorc1.idnrk);
                count = getChildNodeAufnr(nodeMatnr, npmatnr, subindex, depth + 1, resultindex, count);
                //if(layer.equals("0-1-33"))
                zcorcMatnrMap.put(layer, nodeMatnr);
                nodeAufnr.childs.add(layer);
            }

            double totalmaterial = 0;
            if (nodeAufnr.hiveSapZcorc.idnrk.equals("MSA241034G0100")) {
                logger.info("Debug");
            }
            for (String layer : nodeAufnr.childs) {
                ZcorcMatnr nodeMatnr = zcorcMatnrMap.get(layer);
                totalmaterial += nodeMatnr.hiveSapZcorc.rkst001;
            }

            nodeAufnr.stageprice = nodeAufnr.hiveSapZcorc.rkst001 - totalmaterial;
            if (nodeAufnr.stageprice > 0) {
                logger.info("debug");
            }
        }
        return count;
    }


    public void getHiveRealCost(ZcorcProduct nodeProduct, int resultindex, String batchymonth) {
        try {
            int index = 0;
            Gson gson = new Gson();
            String tablename = " sap_zcorc_result";
            List<HiveSapZcorc> hiveSapZcorcs = tempSapZcorcList.get("0");
            //if (hiveSapZcorcs.size() > 0) {
            for (HiveSapZcorc hiveSapZcorc : hiveSapZcorcs) {
                //if (hiveSapZcorc.matnr.equals(nodeProduct.matnr) &&
                //        hiveSapZcorc.layer.equals(nodeProduct.layer) &&
                //         hiveSapZcorc.aufnr.equals(nodeProduct.aufnr) &&
                //         hiveSapZcorc.idnrk.equals(nodeProduct.matnr)) {

                //HiveSapZcorc hiveSapZcorc2 = gson.fromJson(gson.toJson(hiveSapZcorcs.get(0)), HiveSapZcorc.class);
                HiveSapZcorc hiveSapZcorc2 = gson.fromJson(gson.toJson(hiveSapZcorc), HiveSapZcorc.class);
                //if(hiveSapZcorc2.aufnr==null||!hiveSapZcorc2.aufnr.equals(nodeProduct.aufnr)){
                //    continue;
                //}
                hiveSapZcorc2.ReplaceActual();

                ZcorcAufnr nodeAufnr = new ZcorcAufnr();
                nodeAufnr.hiveSapZcorc = hiveSapZcorc2;
                //FillNodeAufnrAuart(nodeAufnr.hiveSapZcorc);
                getHiveProcess(nodeAufnr, resultindex, batchymonth.equals(""));
                //getChildNodeMatnr(nodeAufnr);
                //nodeProduct.nodeAufnrs.add(nodeAufnr);
                //getTotalSapZcorc(nodeProduct);
                List<String> pmatnrs = new ArrayList<>();
                String strindex = "";
                getChildNodeMatnr(nodeAufnr, pmatnrs, strindex, 1, resultindex, index);
                nodeProduct.nodeAufnrs.add(nodeAufnr);
                zcorcAufnrMap.put(nodeAufnr.hiveSapZcorc.layer, nodeAufnr);
                // }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    public void CheckProductPriceAufnr(ZcorcAufnr nodeAufnr, int resultindex) {
        //for (ZcorcAufnr nodeAufnr:zcorcProduct.nodeAufnrs) {
        double productprice = nodeAufnr.hiveSapZcorc.rkst0051;
        double materialprice = nodeAufnr.hiveSapZcorc.rkst001;
        double childprice = 0;
        double childmaterial = 0;
        for (String layer : nodeAufnr.childs) {
            ZcorcMatnr nodeMatnr = zcorcMatnrMap.get(layer);
            childprice += nodeMatnr.hiveSapZcorc.rkst0051;
            childmaterial += nodeMatnr.hiveSapZcorc.rkst001;
        }
        childmaterial += nodeAufnr.stageprice;
        childprice += nodeAufnr.hiveSapZcorc.getStageProduct();
        double productdiff = Math.abs(childprice - productprice);
        if (productdiff > 1) {
            //logger.info("工单制费不等："+nodeAufnr.hiveSapZcorc.layer+" "+productdiff);
            AddMingLog(1, "工单制费不等：" + nodeAufnr.hiveSapZcorc.layer + " " + productdiff, resultindex);
        }
        double mdiff = Math.abs(materialprice - childmaterial);
        if (mdiff > 1) {
            //logger.info("材料费用不等："+nodeAufnr.hiveSapZcorc.layer+" "+mdiff);
            AddMingLog(1, "材料费用不等：" + nodeAufnr.hiveSapZcorc.layer + " " + mdiff, resultindex);
        }
        for (String layer : nodeAufnr.childs) {
            ZcorcMatnr nodeMatnr = zcorcMatnrMap.get(layer);
            CheckProductPriceMatnr(nodeMatnr, resultindex);
        }
        // }
    }

    public void CheckProductPriceMatnr(ZcorcMatnr nodeMatnr, int resultindex) {
        double productprice = nodeMatnr.hiveSapZcorc.rkst0051;
        double childprice = 0;
        for (String layer : nodeMatnr.childs) {
            ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(layer);
            CheckProductPriceAufnr(nodeAufnr, resultindex);
            childprice += nodeAufnr.hiveSapZcorc.rkst0051 * nodeAufnr.rate * nodeMatnr.hiveSapZcorc.menge / nodeAufnr.hiveSapZcorc.rpsmng;
        }
        childprice += nodeMatnr.hiveSapZcorc.getStageProduct();
        if (Math.abs(childprice - productprice) > 1) {
            // logger.info("物料制费不等："+nodeMatnr.hiveSapZcorc.layer+" "+(childprice-productprice));
        }
    }

    public boolean AddAufnr(ZcorcAufnrDiff zcorcAufnr, String aufnr) {
        boolean bExist = false;
        if (aufnr == null) {
            return bExist;
        }
        for (String fnr : zcorcAufnr.aufnrs) {
            if (fnr.equals(aufnr)) {
                bExist = true;
                break;
            }
        }
        if (!bExist) {
            zcorcAufnr.aufnrs.add(aufnr);
        }
        return bExist;
    }

    public void AddtoList(Map<String, ZcorcAufnrDiff> aufnrDiffList, ZcorcAufnrDiff aufnrDiff, int resultindex, boolean addUse) {
        boolean bExist = false;
        if(aufnrDiff.matnr.equals("41030020002800")){
           logger.info("Debug");
        }
        String month = aufnrDiff.budat;
        if (aufnrDiff.budat.length() > 6) {
            month = aufnrDiff.budat.substring(0, 6);
        }

        //String month = aufnrDiff.budat.substring(0, 6);
        //String key = aufnrDiff.costcenter + "-" + aufnrDiff.matnr + "-" + month;
        String key = aufnrDiff.matnr;
        if (aufnrDiff.costcenter.equals("2000080321") && aufnrDiff.matnr.equals("28500000082601")) {
            //logger.info("Debug");
            logger.info(JSON.toJSONString(aufnrDiff));
        }
        if (aufnrDiffList.containsKey(key)) {
            ZcorcAufnrDiff aufnrDiff1 = aufnrDiffList.get(key);
            //for (ZcorcAufnrDiff aufnrDiff1 : aufnrDiffList) {
            //if (aufnrDiff.costcenter.equals(aufnrDiff1.costcenter) && aufnrDiff.matnr.equals(aufnrDiff1.matnr)) {
            //if (aufnrDiff.budat.length() > 6 && aufnrDiff1.budat.length() > 6) {
            //String month1 = aufnrDiff.budat.substring(0, 6);
            //String month2 = aufnrDiff1.budat.substring(0, 6);
            //if (month1.equals(month2)) {
            //if(aufnrDiff.matnr.equals("28800002400600")&&month1.equals("202001")&aufnrDiff.costcenter.equals("2000080482")){
            //    logger.info("Debug");
            //}
            //boolean bAufnrExist=AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
            double totaluse = aufnrDiff1.productuse;
            ;//aufnrDiff.productuse + aufnrDiff1.productuse;
            if (addUse) {
                totaluse = aufnrDiff.productuse + aufnrDiff1.productuse;
            }
            aufnrDiff1.laborCalculate.mergeReal(aufnrDiff.laborCalculate, addUse);
            //if(aufnrDiff.matnr.equals("28100004605000")&&month1.equals("202001")&aufnrDiff.costcenter.equals("2000080217")){
            //logger.info(""+aufnrDiff1.laborCalculate.aufnruse+","+aufnrDiff1.laborCalculate.aufnrnum);
            //}
            aufnrDiff1.zjCalculate.mergeReal(aufnrDiff.zjCalculate, addUse);
            aufnrDiff1.rdCalculate.mergeReal(aufnrDiff.rdCalculate, addUse);
            aufnrDiff1.flCalculate.mergeReal(aufnrDiff.flCalculate, addUse);
            aufnrDiff1.qtCalculate.mergeReal(aufnrDiff.qtCalculate, addUse);
            aufnrDiff1.productuse = totaluse;
            //aufnrDiff1.productuse = aufnrDiff1.laborCalculate.aufnruse;
            aufnrDiff1.realchildcount = aufnrDiff1.realchildcount + 1;
            AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
            //aufnrDiff1.realChilds.add(aufnrDiff);
            //boolean bExist=AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
            //AddMiningAufnrDetail(aufnrDiff.matnr, aufnrDiff.costcenter, aufnrDiff.budat, aufnrDiff, "real", resultindex,aufnrDiff1.realchildcount);
            aufnrDiff1.Cal();
            aufnrDiffList.put(key, aufnrDiff1);

            //bExist = true;
            //break;
            //}
//                } else if (aufnrDiff.budat.equals(aufnrDiff1.budat)) {
//                    //boolean bAufnrExist=AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
//                    double totaluse = aufnrDiff1.productuse;;//aufnrDiff.productuse + aufnrDiff1.productuse;
//                    if(addUse){
//                        totaluse=aufnrDiff.productuse + aufnrDiff1.productuse;
//                    }
//                    //double totaluse = aufnrDiff.productuse + aufnrDiff1.productuse;
//                    aufnrDiff1.laborCalculate.mergeReal(aufnrDiff.laborCalculate,addUse);
//                    aufnrDiff1.zjCalculate.mergeReal(aufnrDiff.zjCalculate,addUse);
//                    aufnrDiff1.rdCalculate.mergeReal(aufnrDiff.rdCalculate,addUse);
//                    aufnrDiff1.flCalculate.mergeReal(aufnrDiff.flCalculate,addUse);
//                    aufnrDiff1.qtCalculate.mergeReal(aufnrDiff.qtCalculate,addUse);
//                    aufnrDiff1.productuse = totaluse;
//                    aufnrDiff1.realchildcount = aufnrDiff1.realchildcount + 1;
//                    AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
//                    //aufnrDiff1.realChilds.add(aufnrDiff);
//                    //AddMiningAufnrDetail(aufnrDiff.matnr, aufnrDiff.costcenter, aufnrDiff.budat, aufnrDiff, "real", resultindex,aufnrDiff1.realchildcount);
//                    aufnrDiff1.Cal();
//
//                    bExist = true;
//                    break;
//                }
            //}
        } else {
            //if (!bExist) {
            Gson gson = new Gson();
            try {
                ZcorcAufnrDiff aufnrDiff1 = gson.fromJson(gson.toJson(aufnrDiff), ZcorcAufnrDiff.class);
                aufnrDiff1.realchildcount = 1;
                AddAufnr(aufnrDiff1, aufnrDiff1.aufnr);
                //AddMiningAufnrDetail(aufnrDiff.matnr, aufnrDiff.costcenter, aufnrDiff.budat, aufnrDiff, "real", resultindex,aufnrDiff1.realchildcount);
                //aufnrDiff.realChilds.add(aufnrDiff1);
                //aufnrDiffList.add(aufnrDiff1);
                aufnrDiffList.put(key, aufnrDiff1);
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
        }
    }

    public void AddMiningMaterialDetail(ZcorcMaterialDiff materialDetail, int resultindex) {
        //try {
//        Gson gson = new Gson();
//        //double diff = totalDiff.realmaterial - totalDiff.stdmaterial;
//        //List<MiningMaterial> miningMaterials=new ArrayList<>();
//        //for (MaterialDiff materialDetail : materialDiffList) {
//        MiningMaterialdetail miningMaterial = new MiningMaterialdetail();
//        miningMaterial.setMatnr(materialDetail.matnr);
//        miningMaterial.setResultid(resultindex);
//        //miningMaterial.setAufnr(miningResultWithBLOBs.getAufnr());
//        // miningMaterial.setVersion(miningResultWithBLOBs.getVersion());
//        miningMaterial.setJsondata(gson.toJson(materialDetail));
//        //miningMaterial.setTotaldiff(new BigDecimal(materialDetail.totaldiff));
//        //if (diff != 0) {
//        //    miningMaterial.setRatio(new BigDecimal(Math.abs(materialDetail.totaldiff / diff)));
//        // } else {
//        //     miningMaterial.setRatio(new BigDecimal(0));
//        // }
//        //miningMaterials.add(miningMaterial);
//        //materialdetailMapper.insert(miningMaterial);
//        if (activeprofile.equals("idle")) {
//            amqpService.SendMessage("idle-mining-material-detail", gson.toJson(miningMaterial));
//        } else {
//            amqpService.SendMessage("mining-material-detail", gson.toJson(miningMaterial));
//        }
        //amqpService.SendMessage("mining-material-detail", gson.toJson(miningMaterial));
        //}
        // } catch (Exception e) {
        //     logger.info(e.getMessage());
        // }
    }

    public void AddtoDetail(ZcorcMaterialDiff materialDiff, int resultindex) {
        AddMiningMaterialDetail(materialDiff, resultindex);
//        if(materialDetailMap.containsKey(materialDiff.matnr)){
//            List<ZcorcMaterialDiff> materialDiffs=materialDetailMap.get(materialDiff.matnr);
//            materialDiffs.add(materialDiff);
//            materialDetailMap.put(materialDiff.matnr,materialDiffs);
//        }else{
//            List<ZcorcMaterialDiff> materialDiffs=new ArrayList<>();
//            materialDiffs.add(materialDiff);
//            materialDetailMap.put(materialDiff.matnr,materialDiffs);
//        }
    }

    public void AddtoList(Map<String, ZcorcMaterialDiff> materialDiffMap, ZcorcMaterialDiff materialDiff, int resultindex, boolean addDetail) {
        if (materialDiff.realuse == 0) {
            return;
        }
        if(materialDiff.matnr.equals("21010120080000")){
            //logger.info("21010120080000");
        }
        boolean bExist = false;
        if (true) {
            //return;
        }
        if (materialDiffMap.containsKey(materialDiff.matnr)) {
            //for (MaterialDiff materialDiff1 : materialDiffList) {
            //if (materialDiff.matnr.equals(materialDiff1.matnr)) {
            //if(materialDiff.meng==0){
            //    return;

            //}
            if (materialDiff.matnr.equals("29010030182000")) {
                logger.info("Debug");
                //debugList.add(materialDiff);
            }
            ZcorcMaterialDiff materialDiff1 = materialDiffMap.get(materialDiff.matnr);
            double totalcost1 = materialDiff1.realuse * materialDiff1.realcost;
            double totalcost2 = materialDiff.realuse * materialDiff.realcost;
            double totaluse = materialDiff1.realuse + materialDiff.realuse;
            materialDiff1.realuse = totaluse;
            materialDiff1.realcost = (totalcost1 + totalcost2) / totaluse;
            if (totaluse == 0) {
                logger.info("Exception totaluse is 0");
                //materialDiffList.remove(materialDiff1);
                //return;
                materialDiff1.realcost = 0;
            }

            if (addDetail) {
                AddtoDetail(materialDiff, resultindex);
            }
            //AddtoDetail(materialDiff, resultindex);
            //materialDiff1.childs.add(materialDiff);

            //materialDiff1.realmap.put(materialDiff.parent, materialDiff.realuse);
            bExist = true;
            materialDiff1.Cal();
            materialDiffMap.put(materialDiff1.matnr, materialDiff1);
            // break;
            //}
        } else {
            materialDiff.Cal();
            AddtoDetail(materialDiff, resultindex);
            materialDiffMap.put(materialDiff.matnr, materialDiff);
        }
        //if (!bExist) {
        //     materialDiff.Cal();
        //    materialDiffList.add(materialDiff);
        //}
    }

    public void generateAufnrDiff(ZcorcMatnr nodeMatnr, Map<String, ZcorcAufnrDiff> materialDiffList, double bomuse, int resultindex, String pos) {
        int index = 0;
        for (String layer : nodeMatnr.childs) {
            String pos1 = pos + "[" + index + "/" + nodeMatnr.childs.size() + "]";
            //logger.info("generateAufnrDiff:" + pos1);
            ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(layer);
            generateAufnrDiff(nodeAufnr, materialDiffList, nodeMatnr.hiveSapZcorc.unmng * bomuse, resultindex, pos1);
            index++;
        }
        if (nodeMatnr.childs.size() == 0 && nodeMatnr.hiveSapZcorc.rkst0051 > 0) {
            if (nodeMatnr.hiveSapZcorc.matnr.equals("28100004605000")) {
                logger.info("Debug");
            }
            ZcorcAufnrDiff aufnrDiff = new ZcorcAufnrDiff(nodeMatnr, bomuse);
            AddtoList(materialDiffList, aufnrDiff, resultindex, true);
        }
        //if(nodeMatnr.childs.size()==0&&nodeMatnr.hiveSapZcorc.)
    }

    public void generateAufnrDiff(ZcorcAufnr nodeAufnr, Map<String, ZcorcAufnrDiff> materialDiffList, double bomuse, int resultindex, String pos) {
        if (nodeAufnr.hiveSapZcorc.aufnr != null && nodeAufnr.hiveSapZcorc.aufnr.equals("000100899758")) {
            logger.debug("debug");
        }
        if (layerAufnrMap.containsKey(nodeAufnr.hiveSapZcorc.layer)) {
            Map<String, ZcorcAufnrDiff> aufnrDiffMap = layerAufnrMap.get(nodeAufnr.hiveSapZcorc.layer);
            for (ZcorcAufnrDiff zcorcAufnrDiff : aufnrDiffMap.values()) {
                //ZcorcAufnrDiff aufnrDiff = new ZcorcAufnrDiff(nodeMatnr, bomuse);
                ZcorcAufnrDiff aufnrDiff = JSON.parseObject(JSON.toJSONString(zcorcAufnrDiff), ZcorcAufnrDiff.class);
                //if(nodeAufnr.hiveSapZcorc.rpsmng!=0) {
                aufnrDiff.productuse = bomuse * aufnrDiff.productuse;
                aufnrDiff.Cal();
                AddtoList(materialDiffList, aufnrDiff, resultindex, true);
                //}else{
                //    logger.info(JSON.toJSONString(nodeAufnr));
                //}
            }
        } else {
            //logger.info("generateAufnrDiff:" + nodeAufnr.hiveSapZcorc.layer);
            double totallabor = 0;
            double totalproduct = 0;
            //boolean bFirst=true;
            Map<CostcenterMonth, List<HiveSapAfru>> map = new HashMap<>();
            for (HiveSapAfru hiveSapAfru : nodeAufnr.hiveSapAfruList) {
                CostcenterMonth costcenterMonth = new CostcenterMonth(hiveSapAfru);
                if (map.containsKey(costcenterMonth)) {
                    List<HiveSapAfru> hiveSapAfrus = map.get(costcenterMonth);
                    hiveSapAfrus.add(hiveSapAfru);
                    map.put(costcenterMonth, hiveSapAfrus);
                } else {
                    List<HiveSapAfru> hiveSapAfrus = new ArrayList<>();
                    hiveSapAfrus.add(hiveSapAfru);
                    map.put(costcenterMonth, hiveSapAfrus);
                }
            }
            for (CostcenterMonth costcenterMonth : map.keySet()) {
                boolean bFirst = true;
                for (HiveSapAfru hiveSapAfru : map.get(costcenterMonth)) {
                    double rate = hiveSapAfru.lmnga / nodeAufnr.hiveSapZcorc.ppsmng;
                    if (nodeAufnr.hiveSapZcorc.matnr.equals("28100004605000") & hiveSapAfru.kostl.equals("2000080217") & hiveSapAfru.budat.substring(0, 6).equals("202001")) {
                        logger.info("Debug");
                    }
                    if (nodeAufnr.hiveSapZcorc.ppsmng == 0) {
                        logger.info("Debug");
                    }
                    if (rate == 0) {
                        continue;
                    }
                    ZcorcAufnrDiff aufnrDiff = new ZcorcAufnrDiff(hiveSapAfru, nodeAufnr.hiveSapZcorc, bomuse * nodeAufnr.rate * rate);
                    AddtoList(materialDiffList, aufnrDiff, resultindex, bFirst);
                    totallabor += aufnrDiff.laborCalculate.getTotalRealCost();
                    totalproduct += aufnrDiff.totalcostproduct;
                    if (bFirst) {
                        bFirst = false;
                    }
                }
            }
            double diff1 = Math.abs(totallabor - nodeAufnr.hiveSapZcorc.kst003);
            if (diff1 > 1) {
                logger.info("人工不等："+nodeAufnr.hiveSapZcorc.layer+" "+diff1);
            }
            double diff2 = Math.abs(totalproduct - bomuse * nodeAufnr.hiveSapZcorc.getStageProduct() * nodeAufnr.rate / nodeAufnr.hiveSapZcorc.rpsmng);
            if (diff2 > 1) {
                //logger.info("1制费不等："+nodeAufnr.hiveSapZcorc.layer+" "+diff2);
                AddMingLog(1, "1制费不等：" + nodeAufnr.hiveSapZcorc.layer + " " + diff2, resultindex);
            }

            int index = 0;
            for (String layer : nodeAufnr.childs) {
                String pos1 = pos + "[" + index + "/" + nodeAufnr.childs.size() + "]";
                //logger.info("generateAufnrDiff:" + pos1);
                ZcorcMatnr nodeMatnr = zcorcMatnrMap.get(layer);
                //double parentuse = nodeMatnr.hiveSapZcorc.menge / nodeMatnr.hiveSapZcorc.rpsmng;//单位用量
                generateAufnrDiff(nodeMatnr, materialDiffList, bomuse * nodeAufnr.rate, resultindex, pos1);
                index++;
            }
        }
    }

    public void generateAufnrDiff(ZcorcAufnr nodeAufnr, List<ZcorcAufnrDiff> materialDiffList, double bomuse, int resultindex, String player) {
        if (nodeAufnr.hiveSapZcorc.aufnr != null && nodeAufnr.hiveSapZcorc.aufnr.equals("000100899758")) {
            logger.debug("debug");
        }
        logger.info("generateAufnrDiff:" + player);
        double totallabor = 0;
        double totalproduct = 0;
        //boolean bFirst=true;
        Map<CostcenterMonth, List<HiveSapAfru>> map = new HashMap<>();
        for (HiveSapAfru hiveSapAfru : nodeAufnr.hiveSapAfruList) {
            CostcenterMonth costcenterMonth = new CostcenterMonth(hiveSapAfru);
            if (map.containsKey(costcenterMonth)) {
                List<HiveSapAfru> hiveSapAfrus = map.get(costcenterMonth);
                hiveSapAfrus.add(hiveSapAfru);
                map.put(costcenterMonth, hiveSapAfrus);
            } else {
                List<HiveSapAfru> hiveSapAfrus = new ArrayList<>();
                hiveSapAfrus.add(hiveSapAfru);
                map.put(costcenterMonth, hiveSapAfrus);
            }
        }
        for (CostcenterMonth costcenterMonth : map.keySet()) {
            boolean bFirst = true;
            for (HiveSapAfru hiveSapAfru : map.get(costcenterMonth)) {
                double rate = hiveSapAfru.lmnga / nodeAufnr.hiveSapZcorc.ppsmng;
                if (nodeAufnr.hiveSapZcorc.matnr.equals("28100004605000") & hiveSapAfru.kostl.equals("2000080217") & hiveSapAfru.budat.substring(0, 6).equals("202001")) {
                    logger.info("Debug");
                }
                ZcorcAufnrDiff aufnrDiff = new ZcorcAufnrDiff(hiveSapAfru, nodeAufnr.hiveSapZcorc, bomuse * nodeAufnr.rate * rate);
                AddtoList(materialDiffList, aufnrDiff, resultindex, bFirst);
                totallabor += aufnrDiff.laborCalculate.getTotalRealCost();
                totalproduct += aufnrDiff.totalcostproduct;
                if (bFirst) {
                    bFirst = false;
                }
            }
        }
        double diff1 = Math.abs(totallabor - nodeAufnr.hiveSapZcorc.kst003);
        if (diff1 > 1) {
            //logger.info("人工不等："+nodeAufnr.hiveSapZcorc.layer+" "+diff1);
        }
        double diff2 = Math.abs(totalproduct - bomuse * nodeAufnr.hiveSapZcorc.getStageProduct() * nodeAufnr.rate / nodeAufnr.hiveSapZcorc.rpsmng);
        if (diff2 > 1) {
            //logger.info("1制费不等："+nodeAufnr.hiveSapZcorc.layer+" "+diff2);
            AddMingLog(1, "1制费不等：" + nodeAufnr.hiveSapZcorc.layer + " " + diff2, resultindex);
        }
        for (String layer : nodeAufnr.childs) {
            ZcorcMatnr nodeMatnr = zcorcMatnrMap.get(layer);
            //double parentuse = nodeMatnr.hiveSapZcorc.menge / nodeMatnr.hiveSapZcorc.rpsmng;//单位用量
            generateAufnrDiff(nodeMatnr, materialDiffList, bomuse * nodeAufnr.rate, resultindex, player + "[" + layer + "]");
        }
    }

    public void AddtoList(List<ZcorcAufnrDiff> aufnrDiffList, ZcorcAufnrDiff aufnrDiff, int resultindex, boolean addUse) {
        boolean bExist = false;
        //if(aufnrDiff.matnr.equals("0902016938")){
        //   logger.info("Debug");
        //}
        for (ZcorcAufnrDiff aufnrDiff1 : aufnrDiffList) {
            if (aufnrDiff.costcenter.equals(aufnrDiff1.costcenter) && aufnrDiff.matnr.equals(aufnrDiff1.matnr)) {
                if (aufnrDiff.budat.length() > 6 && aufnrDiff1.budat.length() > 6) {
                    String month1 = aufnrDiff.budat.substring(0, 6);
                    String month2 = aufnrDiff1.budat.substring(0, 6);
                    if (month1.equals(month2)) {
                        if (aufnrDiff.matnr.equals("28800002400600") && month1.equals("202001") & aufnrDiff.costcenter.equals("2000080482")) {
                            logger.info("Debug");
                        }
                        //boolean bAufnrExist=AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
                        double totaluse = aufnrDiff1.productuse;
                        ;//aufnrDiff.productuse + aufnrDiff1.productuse;
                        if (addUse) {
                            totaluse = aufnrDiff.productuse + aufnrDiff1.productuse;
                        }
                        aufnrDiff1.laborCalculate.mergeReal(aufnrDiff.laborCalculate, addUse);
                        if (aufnrDiff.matnr.equals("28100004605000") && month1.equals("202001") & aufnrDiff.costcenter.equals("2000080217")) {
                            //logger.info(""+aufnrDiff1.laborCalculate.aufnruse+","+aufnrDiff1.laborCalculate.aufnrnum);
                        }
                        aufnrDiff1.zjCalculate.mergeReal(aufnrDiff.zjCalculate, addUse);
                        aufnrDiff1.rdCalculate.mergeReal(aufnrDiff.rdCalculate, addUse);
                        aufnrDiff1.flCalculate.mergeReal(aufnrDiff.flCalculate, addUse);
                        aufnrDiff1.qtCalculate.mergeReal(aufnrDiff.qtCalculate, addUse);
                        aufnrDiff1.productuse = totaluse;
                        //aufnrDiff1.productuse = aufnrDiff1.laborCalculate.aufnruse;
                        aufnrDiff1.realchildcount = aufnrDiff1.realchildcount + 1;
                        AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
                        //aufnrDiff1.realChilds.add(aufnrDiff);
                        //boolean bExist=AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
                        //AddMiningAufnrDetail(aufnrDiff.matnr, aufnrDiff.costcenter, aufnrDiff.budat, aufnrDiff, "real", resultindex,aufnrDiff1.realchildcount);
                        aufnrDiff1.Cal();

                        bExist = true;
                        break;
                    }
                } else if (aufnrDiff.budat.equals(aufnrDiff1.budat)) {
                    //boolean bAufnrExist=AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
                    double totaluse = aufnrDiff1.productuse;
                    ;//aufnrDiff.productuse + aufnrDiff1.productuse;
                    if (addUse) {
                        totaluse = aufnrDiff.productuse + aufnrDiff1.productuse;
                    }
                    //double totaluse = aufnrDiff.productuse + aufnrDiff1.productuse;
                    aufnrDiff1.laborCalculate.mergeReal(aufnrDiff.laborCalculate, addUse);
                    aufnrDiff1.zjCalculate.mergeReal(aufnrDiff.zjCalculate, addUse);
                    aufnrDiff1.rdCalculate.mergeReal(aufnrDiff.rdCalculate, addUse);
                    aufnrDiff1.flCalculate.mergeReal(aufnrDiff.flCalculate, addUse);
                    aufnrDiff1.qtCalculate.mergeReal(aufnrDiff.qtCalculate, addUse);
                    aufnrDiff1.productuse = totaluse;
                    aufnrDiff1.realchildcount = aufnrDiff1.realchildcount + 1;
                    AddAufnr(aufnrDiff1, aufnrDiff.aufnr);
                    //aufnrDiff1.realChilds.add(aufnrDiff);
                    //AddMiningAufnrDetail(aufnrDiff.matnr, aufnrDiff.costcenter, aufnrDiff.budat, aufnrDiff, "real", resultindex,aufnrDiff1.realchildcount);
                    aufnrDiff1.Cal();

                    bExist = true;
                    break;
                }
            }
        }
        if (!bExist) {
            Gson gson = new Gson();
            ZcorcAufnrDiff aufnrDiff1 = gson.fromJson(gson.toJson(aufnrDiff), ZcorcAufnrDiff.class);
            aufnrDiff1.realchildcount = 1;
            AddAufnr(aufnrDiff1, aufnrDiff1.aufnr);
            //AddMiningAufnrDetail(aufnrDiff.matnr, aufnrDiff.costcenter, aufnrDiff.budat, aufnrDiff, "real", resultindex,aufnrDiff1.realchildcount);
            //aufnrDiff.realChilds.add(aufnrDiff1);
            aufnrDiffList.add(aufnrDiff1);
        }
    }

    public void generateAufnrDiff(ZcorcMatnr nodeMatnr, List<ZcorcAufnrDiff> materialDiffList, double bomuse, int resultindex, String player) {
        for (String layer : nodeMatnr.childs) {
            ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(layer);
            generateAufnrDiff(nodeAufnr, materialDiffList, nodeMatnr.hiveSapZcorc.unmng * bomuse, resultindex, player + "[" + layer + "]");
        }
        if (nodeMatnr.childs.size() == 0 && nodeMatnr.hiveSapZcorc.rkst0051 > 0) {
            if (nodeMatnr.hiveSapZcorc.matnr.equals("28100004605000")) {
                logger.info("Debug");
            }
            ZcorcAufnrDiff aufnrDiff = new ZcorcAufnrDiff(nodeMatnr, bomuse);
            AddtoList(materialDiffList, aufnrDiff, resultindex, true);
        }
        //if(nodeMatnr.childs.size()==0&&nodeMatnr.hiveSapZcorc.)
    }

    public void generateMateirialDiffAufnr(Map<String, ZcorcMaterialDiff> materialDiffMap, String aufnrlayer, double bomuse, int level, String pos, int resultindex, boolean addDetail, int materialcount) {
        if (aufnrlayer.equals("0-1-33")) {
            logger.info("Level :" + level + " generateMateirialDiff ");
        }
        //logger.info("generateMateirialDiff "+nodeAufnr.hiveSapZcorc.layer);
        //materialcount++;
        ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(aufnrlayer);
        //logger.info("generateMateirialDiff " + nodeAufnr.hiveSapZcorc.layer);
        if (nodeAufnr.hiveSapZcorc.layer.equals("0-1-47-3-1-8-0")) {
            logger.info("debug");
        }
        int index = 0;
        for (String layer : nodeAufnr.childs) {
            index++;
            materialcount++;
            //ZcorcMatnr nodeMatnr = zcorcMatnrMap.get(layer);
            String pos1 = pos + "[" + index + "/" + nodeAufnr.childs.size() + "]";
            if (level < 8) {
                //logger.info("generateMateirialDiff:" + pos1 + " " + layer);
            }
            Date dt1 = new Date();
            //logger.info("generateMateirialDiff:" + pos1 + " " + layer);
            //materialcount=
            generateMateirialDiffMatnr(materialDiffMap, layer, nodeAufnr.rate * bomuse, level + 1, pos1, resultindex, addDetail, materialcount);
            Date dt2 = new Date();
            long span = dt2.getTime() - dt1.getTime();
            if (level < 6) {
                //logger.info("generateMateirialDiff:" + pos1 + " " + layer);
                //logger.info("generateMateirialDiff:("+materialcount+"):"+pos1+" span:"+span);
            }
            //logger.info(pos1+" span:"+span);
        }
        if (nodeAufnr.stageprice > 0) {
            //Date dt1=new Date();
            ZcorcMaterialDiff materialDiff = new ZcorcMaterialDiff(nodeAufnr, bomuse);
            AddtoList(materialDiffMap, materialDiff, resultindex, addDetail);
            //Date dt2=new Date();
            //long span=dt2.getTime()-dt1.getTime();
            //logger.info("stageprice span:"+span);
        }
        //return materialcount;
    }

    public void generateMateirialDiffMatnr(Map<String, ZcorcMaterialDiff> materialDiffMap, String matnrLayer, double rate, int level, String pos, int resultindex, boolean addDetail, int materialcount) {
        //materialcount++;
        if (matnrLayer.equals("0-1-33")) {
            logger.info("Level :" + level + " generateMateirialDiffMatnr ");
        }
        ZcorcMatnr nodeMatnr = zcorcMatnrMap.get(matnrLayer);
        if (nodeMatnr.hiveSapZcorc.rlayer != "" && nodeMatnr.hiveSapZcorc.rlayer != null) {
            matnrLayer = nodeMatnr.hiveSapZcorc.rlayer;
        }
        if (nodeMatnr.childs.size() == 0) {
            if (nodeMatnr.hiveSapZcorc.rkst001 != 0) {
                String layer = nodeMatnr.hiveSapZcorc.layer;
                if (layer.contains("0-73-5-1-10-1-1")) {
                    logger.info("Add material diff:" + layer);
                }
                //if(level<10){
                //    logger.info("Level :"+level+" generateMateirialDiff "+nodeMatnr.hiveSapZcorc.layer);
                //}
                //logger.info("generateMateirialDiff "+layer);

                ZcorcMaterialDiff materialDiff = new ZcorcMaterialDiff(nodeMatnr, rate);
                //materialDiff.parent = parent;
                //if (nodeMatnr.hiveSapZcorc.rkst0051 > 0) {

                //}
                AddtoList(materialDiffMap, materialDiff, resultindex, addDetail);
            }
        } else {
            //外协件有本阶材料成本
            //if (nodeMatnr.hiveSapZcorc.ebeln.trim().length() > 0) {
//            if (nodeMatnr.stageprice > 0) {
//                MaterialDiff materialDiff = new MaterialDiff(nodeMatnr, rate);
//                materialDiff.realcost = nodeMatnr.stageprice;
//                //materialDiff.meng=0;
//                AddtoList(materialDiffList, materialDiff);
//            }
        }
        double parentuse = nodeMatnr.hiveSapZcorc.menge / nodeMatnr.hiveSapZcorc.rpsmng;
        if (parentuse != 0) {
            if (rlayerMatnrMap.containsKey(matnrLayer)) {
                Map<String, ZcorcMaterialDiff> zcorcMaterialDiffMap = rlayerMatnrMap.get(matnrLayer);
                for (ZcorcMaterialDiff zcorcMaterialDiff : zcorcMaterialDiffMap.values()) {
                    ZcorcMaterialDiff materialDiff = JSON.parseObject(JSON.toJSONString(zcorcMaterialDiff), ZcorcMaterialDiff.class);
                    materialDiff.realuse = materialDiff.realuse * rate * parentuse;//单位用量
                    AddtoList(materialDiffMap, materialDiff, resultindex, addDetail);
                }
            } else {
                int index = 0;
                for (String layer : nodeMatnr.childs) {
                    index++;
                    materialcount++;
                    String pos1 = pos + "(" + index + "/" + nodeMatnr.childs.size() + ")";
                    //logger.info("generateMateirialDiff:" + pos + " " + layer);
                    //ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(layer);
                    //materialcount=
                    generateMateirialDiffAufnr(materialDiffMap, layer, parentuse * rate, level + 1, pos1, resultindex, addDetail, materialcount);
                }
            }
        }
        //return materialcount;
    }


    //计算累计成本
    public void CalculateAccuCost(StandardMatnr standardMatnr, double bomuse) {
        if (standardMatnr.childs.size() == 0) {
            standardMatnr.dosage = standardMatnr.getParentUse() * bomuse;
            standardMatnr.CalTotal();
        } else {
            for (StandardMatnr matnr : standardMatnr.childs) {
                CalculateAccuCost(matnr, bomuse * standardMatnr.getParentUse());
                standardMatnr.accu_stage.labor += matnr.getParentUse() * (matnr.accu_stage.labor + matnr.stage.labor);
                standardMatnr.accu_stage.equip += matnr.getParentUse() * (matnr.accu_stage.equip + matnr.stage.equip);
                standardMatnr.accu_stage.auxi += matnr.getParentUse() * (matnr.accu_stage.auxi + matnr.stage.auxi);
                standardMatnr.accu_stage.burning += matnr.getParentUse() * (matnr.accu_stage.burning + matnr.stage.burning);
                standardMatnr.accu_stage.other += matnr.getParentUse() * (matnr.accu_stage.other + matnr.stage.other);
                standardMatnr.accu_stage.price += matnr.getParentUse() * (matnr.accu_stage.price + matnr.stage.price);
                standardMatnr.accu_stage.price_material += matnr.getParentUse() * (matnr.accu_stage.price_material + matnr.stage.price_material);
                standardMatnr.accu_stage.price_edcu += matnr.getParentUse() * (matnr.accu_stage.price_edcu + matnr.stage.price_edcu);
                standardMatnr.accu_stage.price_em += matnr.getParentUse() * (matnr.accu_stage.price_em + matnr.stage.price_em);
                //standardMatnr.accu_stage.price7525 += matnr.getParentUse() * (matnr.accu_stage.price7525 + matnr.stage.price7525);
                //standardMatnr.accu_stage.price7525_material += matnr.getParentUse() * (matnr.accu_stage.price7525_material + matnr.stage.price7525_material);
               // standardMatnr.accu_stage.price7525_edcu += matnr.getParentUse() * (matnr.accu_stage.price7525_edcu + matnr.stage.price7525_edcu);
               // standardMatnr.accu_stage.price7525_em += matnr.getParentUse() * (matnr.accu_stage.price7525_em + matnr.stage.price7525_em);
                //standardMatnr.accu_stage.price+=matnr.parentUse*matnr.getTotal();
                //standardMatnr.accu_stage.price7525+=matnr.parentUse*matnr.getTotal7525();
            }
            standardMatnr.dosage = standardMatnr.getParentUse() * bomuse;
            standardMatnr.CalTotal();
        }
    }


    public void FindNode(String matnr, String ymonth, String werks, String version, String aufnr, String batchymonth, boolean saveDetail) {
        int resultindex = -1;
        try {

            logger.info("FindNode " + matnr + " " + aufnr + " " + version);
            AppSceneCostMiningResult miningResultWithBLOBs = new AppSceneCostMiningResult();
            miningResultWithBLOBs.setStartdate(new Date());
            miningResultWithBLOBs.setMatnr(matnr);
            miningResultWithBLOBs.setAufnr(aufnr);
            //miningResultWithBLOBs.setWbs(posid);
            miningResultWithBLOBs.setYmonth(ymonth);
            miningResultWithBLOBs.setVersion(version);
            miningResultWithBLOBs.setWerks(werks);
            //miningResultWithBLOBs.setLgort(getlgort(werks, matnr, posid, ymonth));
            //miningResultWithBLOBs.setPpsmng(new Double(35));
            miningResultWithBLOBs.setTotalreal(new Double(0));
            miningResultWithBLOBs.setTotalstd(new Double(0));
            miningResultWithBLOBs.setBatchymonth(batchymonth);

            iAppSceneCostMiningResultService.save(miningResultWithBLOBs);

            //LoadMiningReason();
            resultindex = miningResultWithBLOBs.getId();

            //updateMiningprojectcate(miningResultWithBLOBs);


            //resultindex = SetStatus(miningResultWithBLOBs, "7%");
            //miningResultWithBLOBs.setStatus("0%");
            //StandardMatnr standardMatnr = standardCostService.loadStandardCost2(matnr, version, nodeProduct.nodeAufnr.hiveSapZcorc.werks);

            //先删除旧的记录，生成新的id
            //miningService.DeleteOldMiningResult(miningResultWithBLOBs);
            //resultindex = SetStatus(miningResultWithBLOBs, "7%");

            //miningService.UpdateMiningResultBlobs(miningResultWithBLOBs);
            InitTempSapZcorc2(matnr, werks, aufnr, ymonth, resultindex);
            LoadMiningReason();
            SetStatus(miningResultWithBLOBs, "10%");


            Gson gson = new Gson();
            ZcorcProduct nodeProduct = new ZcorcProduct(matnr, "", werks, "0-1-0", version);

            StandardMatnr standardMatnr = loadStandardCost2(matnr, version, werks);
            //CalculateAccuCost(standardMatnr, 1);
            //StandardMatnr standardMatnr = standardCostService.processStandardCost(matnr, version, nodeProduct.nodeAufnr.hiveSapZcorc.werks, nodeProduct.batch);
            //getProductBatch(nodeProduct);
            getHiveRealCost(nodeProduct, resultindex, batchymonth);
            for (ZcorcAufnr zcorcAufnr : nodeProduct.nodeAufnrs) {
                CheckProductPriceAufnr(zcorcAufnr, resultindex);
            }
            //CheckProductPriceAufnr(nodeProduct.no,resultindex);

            SetStatus(miningResultWithBLOBs, "20%");
            //miningService.UpdateMiningResultBlobs(miningResultWithBLOBs);
            DateTime dt1 = DateTime.now();
            logger.info(JSON.toJSONString(rlayers));

            //先计算参考层级的物料
            HashSet<String> aufnrLayers = new HashSet<>();
            int rlayerindex = 0;
            TreeSet<String> layers = new TreeSet<>(new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    if (o1.equals(o2)) {
                        return 0;
                    } else if (o1.length() < o2.length()) {
                        return 1;
                    } else {
                        return -1;
                    }
                    //return o1<o2;   //改写排序规则，降序排序
                }
            });
            layers.addAll(aufnrLayers);

            rlayerindex = 0;
            for (String rlayer : layers) {
                //if (rlayer.equals("0-1-14-1-25-1-1-1-1-4-1-2-0")) {
                //    logger.info("Debug");
                //}
                logger.info("calculate aufnr:[" + rlayerindex + "/" + layers.size() + "]:" + rlayer);
                if (zcorcAufnrMap.containsKey(rlayer)) {
                    int materialcount = 0;
                    ZcorcAufnr zcorcAufnr = zcorcAufnrMap.get(rlayer);
                    //double rpsmng = zcorcAufnr.hiveSapZcorc.rpsmng;
                    Map<String, ZcorcAufnrDiff> materialDiffMap = new HashMap<>();
                    generateAufnrDiff(zcorcAufnr, materialDiffMap, 1, resultindex, "");
                    layerAufnrMap.put(rlayer, materialDiffMap);
                }
                rlayerindex++;
            }

            //生成实际材料费
            List<ZcorcMaterialDiff> realMaterialDiffList = new ArrayList<>();
            Map<String, ZcorcMaterialDiff> realMaterialDiffMap = new HashMap<>();
            Map<String, ZcorcMaterialDiff> materialDiffMap = new HashMap<>();
            //materialDiffMap.clear();
            //materialDetailMap.clear();
            double rpsmng = nodeProduct.getRpsmng();
            int materialcount = 0;
            int nodeaufnrindex = 0;
            for (ZcorcAufnr zcorcAufnr : nodeProduct.nodeAufnrs) {
                logger.info("calculate nodeAufnrs:[" + nodeaufnrindex + "/" + nodeProduct.nodeAufnrs.size() + "]");
                generateMateirialDiffAufnr(materialDiffMap, zcorcAufnr.hiveSapZcorc.layer, zcorcAufnr.hiveSapZcorc.rpsmng / rpsmng, 1, "", resultindex, saveDetail, materialcount);
                nodeaufnrindex++;
            }
            SetStatus(miningResultWithBLOBs, "25%");
            for (ZcorcMaterialDiff materialDiff : materialDiffMap.values()) {
                realMaterialDiffList.add(materialDiff);
                //if (materialDiff.matnr.equals("0501060052")) {
                //    logger.info("Debug");
                //}
            }
            DateTime dt2 = DateTime.now();
            //long span = dt2.toDate().getTime() - dt1.toDate().getTime();
            //logger.info("20%-30% span:" + span);
            //String json=gson.toJson(realMaterialDiffList);
            SetStatus(miningResultWithBLOBs, "30%");
            double totalmaterial = 0;
            for (ZcorcMaterialDiff materialDiff : realMaterialDiffList) {
                totalmaterial += materialDiff.realuse * materialDiff.realcost;
            }
            double mdiff = Math.abs(totalmaterial - nodeProduct.getPrice());
            if (Math.abs(mdiff) > 1) {
                //logger.info("实际材料费用不等:" + mdiff);
                AddMingLog(1, "实际材料费用不等:" + mdiff, resultindex);
            }

            //生成实际工费和制费
            List<ZcorcAufnrDiff> realAufnrList = new ArrayList<>();
            Map<String, ZcorcAufnrDiff> realAufnrMap = new HashMap<>();
            //int aufnrindex=0;
            for (ZcorcAufnr zcorcAufnr : nodeProduct.nodeAufnrs) {
                //logger.info("generateAufnrDiff:["+aufnrindex+"/"+nodeProduct.nodeAufnrs.size()+"]");
                generateAufnrDiff(zcorcAufnr, realAufnrMap, zcorcAufnr.hiveSapZcorc.rpsmng / rpsmng, resultindex, "");
                //aufnrindex++;
            }
            for (ZcorcAufnrDiff zcorcAufnrDiff : realAufnrMap.values()) {
                realAufnrList.add(zcorcAufnrDiff);
            }
            SetStatus(miningResultWithBLOBs, "40%");
            double totalproductcost = 0;
            double totalreallabor = 0;
            for (ZcorcAufnrDiff aufnrDiff : realAufnrList) {
                totalproductcost += aufnrDiff.totalcostproduct;
                totalreallabor += aufnrDiff.totalcostlabor;
            }
            double realproductdiff = Math.abs(totalproductcost - nodeProduct.getKst005());
            if (realproductdiff > 1) {
                //logger.info("实际制费不等:" + realproductdiff);
                AddMingLog(1, "实际制费不等:" + realproductdiff, resultindex);
            }
            double reallabordiff = Math.abs(totalreallabor - nodeProduct.getKst003());
            if (realproductdiff > 1) {
                //logger.info("实际人工不等:" + reallabordiff);
                AddMingLog(1, "实际人工不等:" + reallabordiff, resultindex);
            }
            //logger.info("Total product cost:" + totalproductcost);
            //miningService.InsertAufnrDiff(realAufnrList);

            //计算标准成本
            //StandardMatnr standardMatnr = standardCostService.processStandardCost(matnr, version, nodeProduct.nodeAufnr.hiveSapZcorc.werks, nodeProduct.batch);
            //StandardMatnr standardMatnr = standardCostService.loadStandardCost2(matnr, version, nodeProduct.nodeAufnr.hiveSapZcorc.werks);
            //SetStatus(miningResultWithBLOBs,"50%");

            //miningService.UpdateMiningResultBlobs(miningResultWithBLOBs);
            //logger.info("40%");


            //生成标准材料费
            List<ZcorcMaterialDiff> stdMaterialDiffList = new ArrayList<>();
            Map<String, AppSceneCostMaterial> materialMap = getVersionMaterialMap(standardMatnr.version);
            generateZcorcMaterialDiff(standardMatnr, stdMaterialDiffList, 1, materialMap);
            CheckStdMaterial(standardMatnr, resultindex);

            double stdmtotal = 0;
            for (ZcorcMaterialDiff materialDiff : stdMaterialDiffList) {
                stdmtotal += materialDiff.standarduse * materialDiff.standardcost;
            }
            double smdiff = Math.abs(stdmtotal - standardMatnr.stage.price - standardMatnr.accu_stage.price);
            if (Math.abs(smdiff) > 1) {
                //logger.info("标准材料费用不等:" + smdiff);
                AddMingLog(1, "标准材料费用不等:" + smdiff, resultindex);
            }
            SetStatus(miningResultWithBLOBs, "50%");
            //比较实际材料和标准材料
            CombinMaterialDiff(realMaterialDiffList, stdMaterialDiffList);

            double stdmtotal1 = 0;
            for (ZcorcMaterialDiff materialDiff : realMaterialDiffList) {
                stdmtotal1 += materialDiff.standarduse * materialDiff.standardcost;
            }
            //FindMaterialReason(realMaterialDiffList);


            //String jsonmaterialDiffList = gson.toJson(realMaterialDiffList);
            //miningResultWithBLOBs.setMdetail(jsonmaterialDiffList);
            SetStatus(miningResultWithBLOBs, "60%");


            //生成标准工费和制费
            List<AufnrDiff> aufnrDiffs = new ArrayList<>();
            generateAufnrDiff(standardMatnr, aufnrDiffs, 1);
            //SetStatus(miningResultWithBLOBs,"70%");
            //比较实际和标准的工费和制费
            CombinAufnrDiff(realAufnrList, aufnrDiffs);


            double totallabor = 0;
            double totalproduct = 0;
            for (ZcorcAufnrDiff aufnrDiff : realAufnrList) {
                totallabor += aufnrDiff.laborCalculate.getTotalStdCost();
                totalproduct += aufnrDiff.getStdProductcost();
            }
            double difflabor = totallabor - standardMatnr.stage.labor - standardMatnr.accu_stage.labor;
            if (Math.abs(difflabor) > 1) {
                //logger.info("标准人工费用不等："+difflabor);
                AddMingLog(1, "标准人工费用不等:" + difflabor, resultindex);
            }
            double diffproduct = totalproduct - standardMatnr.stage.getproduct() - standardMatnr.accu_stage.getproduct();
            if (Math.abs(diffproduct) > 1) {
                //logger.info("标准制费不等："+diffproduct);
                AddMingLog(1, "标准制费不等:" + diffproduct, resultindex);
            }
            //logger.info("77%");

            //String jsonaufnrDiffs = gson.toJson(realAufnrList);
            //miningResultWithBLOBs.setLabordetail(jsonaufnrDiffs);
            SetStatus(miningResultWithBLOBs, "70%");
            //miningResultWithBLOBs.setStatus("80%");
            //miningService.UpdateMiningResultBlobs(miningResultWithBLOBs);
            //logger.info("80%");


            //生成总结果
            TotalDiff totalDiff = getTotalDiff(nodeProduct, standardMatnr);
            CalculateReason(totalDiff, realMaterialDiffList, realAufnrList);
            //miningResultWithBLOBs.setTotal(gson.toJson(totalDiff));
            miningResultWithBLOBs.setTotalreal(totalDiff.realtotal);
            miningResultWithBLOBs.setTotalstd(totalDiff.stdtotal);
            if (totalDiff.stdtotal > 0) {
                double percent = Math.abs(totalDiff.realtotal - totalDiff.stdtotal) * 100 / totalDiff.stdtotal;
                miningResultWithBLOBs.setPercent(percent);
            }

            miningResultWithBLOBs.setRealmaterial(totalDiff.realmaterial);
            miningResultWithBLOBs.setReallabor(totalDiff.reallabor);
            miningResultWithBLOBs.setRealproductcost(totalDiff.realproduct);

            miningResultWithBLOBs.setStdmaterial(totalDiff.stdmaterial);
            miningResultWithBLOBs.setStdlabor(totalDiff.stdlabor);
            miningResultWithBLOBs.setStdproductcost(totalDiff.stdproduct);

            miningResultWithBLOBs.setEnddate(new Date());
            //miningService.AddMiningJson(gson.toJson(nodeProduct),gson.toJson(standardMatnr));
            //miningResultWithBLOBs.setNodeproduct(gson.toJson(nodeProduct));
            //miningResultWithBLOBs.setStdproduct(gson.toJson(standardMatnr));

            AddOtherDiff(nodeProduct, totalDiff);


            AddZcorcMiningAufnr(miningResultWithBLOBs, realAufnrList, totalDiff, resultindex);
            SetStatus(miningResultWithBLOBs, "80%");
            AddMiningZcorcMaterial(miningResultWithBLOBs, realMaterialDiffList, totalDiff, resultindex);
            SetStatus(miningResultWithBLOBs, "90%");
            AddMiningDiff(totalDiff, resultindex);
            SetStatus(miningResultWithBLOBs, "95%");
            //miningService.AddMiningJson(nodeProduct,resultindex);
            SetStatus(miningResultWithBLOBs, "99%");

            // miningService.UpdateMiningResultBlobs(miningResultWithBLOBs);
            SetStatus(miningResultWithBLOBs, "已完成");

            //updateminingtransfer(miningResultWithBLOBs);

            ClearCach();
            ClearCach(miningResultWithBLOBs.getVersion());
            //ClearCache();
            logger.info(matnr + " Finished!");
        } catch (KNException ex) {
            ClearCach();
            //throw ex;
            AddMingLog(-1, "KNException:" + matnr + " " + ex.getErr(), resultindex);
            //logger.info("KNException:"+matnr+" "+aufnr+" "+ex.getErr());
            CancelMiningResult(werks, matnr, "", version, ex.getErr());
        } catch (Exception e) {
            ClearCach();
            e.printStackTrace();
            AddMingLog(-1, "Exception:" + matnr + " " + e.getMessage(), resultindex);
            CancelMiningResult(werks, matnr, "", version, e.getMessage());
        }
    }

    public void CombinAufnrDiff(List<ZcorcAufnrDiff> realMaterialDiff, List<AufnrDiff> stdMaterialDiff) {
        Gson gson = new Gson();
        for (ZcorcAufnrDiff smd : realMaterialDiff) {
            double realcount = 0;
            for (ZcorcAufnrDiff rmd : realMaterialDiff) {
                //if (smd.costcenter.equals(rmd.costcenter) && smd.matnr.equals(rmd.matnr)) {
                if (smd.matnr.equals(rmd.matnr)) {
                    realcount += rmd.laborCalculate.aufnruse;
                }
            }
            smd.totalproductuse = realcount;
        }
        for (AufnrDiff smd : stdMaterialDiff) {
            boolean bExist = false;
            if (smd.matnr.equals("28800002400600")) {
                logger.info("Debug");
            }
            //double realcount=0;
            for (ZcorcAufnrDiff rmd : realMaterialDiff) {
                //if (smd.costcenter.equals(rmd.costcenter) && smd.matnr.equals(rmd.matnr)) {
                if (smd.matnr.equals(rmd.matnr)) {
                    // realcount+=rmd.laborCalculate.aufnruse;
                    bExist = true;
                    break;
                }
            }
            if (smd.matnr.equals("0902016938")) {
                logger.info("Debug");
            }

            if (bExist) {
                for (ZcorcAufnrDiff rmd : realMaterialDiff) {
                    //if (smd.processname.equals(rmd.processname) && smd.costcenter.equals(rmd.costcenter) &&
                    //        smd.matnr.equals(rmd.matnr)) {
                   // if (smd.costcenter.equals(rmd.costcenter) && smd.matnr.equals(rmd.matnr)) {
                    if (smd.matnr.equals(rmd.matnr)) {
                        rmd.MergeStandard(smd, rmd.totalproductuse);
                        //rmd.totalproductuse=realcount;
                        rmd.totalbomuse = smd.bomuse;
                        //rmd.productProcessMaintenance=smd.productProcessMaintenance;
                        //rmd.productProcessMaintenance = smd.productProcessMaintenance;
                        //rmd.batch = smd.batch;
                        //rmd.bomuse = smd.bomuse;
                        //bExist = true;
                        //break;
                    }
                }
            } else {
                ZcorcAufnrDiff zcorcAufnrDiff = gson.fromJson(gson.toJson(smd), ZcorcAufnrDiff.class);
                zcorcAufnrDiff.totalbomuse = zcorcAufnrDiff.bomuse;
                realMaterialDiff.add(zcorcAufnrDiff);
            }
            //if (!bExist) {
            //Gson gson=new Gson();
            //    ZcorcAufnrDiff zcorcAufnrDiff = gson.fromJson(gson.toJson(smd), ZcorcAufnrDiff.class);
            //    realMaterialDiff.add(zcorcAufnrDiff);
            //}
        }

        for (ZcorcAufnrDiff aufnrDiff : realMaterialDiff) {
            AppSceneCostMaterial material1 = getMaterial(aufnrDiff.matnr);
            if (material1 != null) {
                aufnrDiff.materialname = material1.getProductName();
            }
            //if (costCenterMap.containsKey(aufnrDiff.costcenter)) {
            //    aufnrDiff.costcentername = costCenterMap.get(aufnrDiff.costcenter).getCostCenterName();
            //}

            FindAufnrReason(aufnrDiff);

        }
    }

    public void FindAufnrReason(ZcorcAufnrDiff aufnrDiff) {
        //if (aufnrDiff.hiveSapAfru != null && aufnrDiff.productProcessMaintenance != null) {
        if (Math.abs(aufnrDiff.laborCalculate.realuse - aufnrDiff.laborCalculate.standarduse) > 1) {
            aufnrDiff.laborcode = "3101";
            aufnrDiff.laborreason = getReason(aufnrDiff.laborcode);
        } else if (aufnrDiff.laborCalculate.realcost != aufnrDiff.laborCalculate.standardcost) {
            aufnrDiff.laborcode = "3201";
            aufnrDiff.laborreason = getReason(aufnrDiff.laborcode);
        }

        double productrealuse = aufnrDiff.getProductRealUse();
        double productstduse = aufnrDiff.getProductStdUse();
        if (Math.abs(productrealuse - productstduse) > 1) {
            //if (Math.abs(aufnrDiff.getProductNumDiff()) > Math.abs(aufnrDiff.getProductDiff())) {
            aufnrDiff.productcode = "3101";
            aufnrDiff.productreason = getReason(aufnrDiff.productcode);
        } else if (Math.abs(aufnrDiff.getProductDiff()) > 1) {
            aufnrDiff.productcode = "3201";
            aufnrDiff.productreason = getReason(aufnrDiff.productcode);
        }


        // }
        if (aufnrDiff.laborcode == null) {
            aufnrDiff.laborcode = "3101";
            aufnrDiff.laborreason = getReason(aufnrDiff.laborcode);
        }

        if (aufnrDiff.productcode == null) {
            aufnrDiff.productcode = "3101";
            aufnrDiff.productreason = getReason(aufnrDiff.productcode);
        }
    }

    public void generateAufnrDiff(StandardMatnr standardMatnr, List<AufnrDiff> aufnrDiffList, double parentuse) {
        if (standardMatnr.productProcessMaintenanceList.size() > 0) {
            boolean bAdduse = true;
            for (AppSceneCostStandardProductprocess productProcessMaintenance : standardMatnr.productProcessMaintenanceList) {
                //HourRate hourRate=getHourRate(productProcessMaintenance.getCostCenterCode(),productProcessMaintenance.getFactory());
                AufnrDiff aufnrDiff = new AufnrDiff(productProcessMaintenance, parentuse * standardMatnr.getParentUse());
                AddtoList(aufnrDiffList, aufnrDiff, bAdduse);
                bAdduse = false;
            }
        }

        for (StandardMatnr standardMatnr1 : standardMatnr.childs) {
            generateAufnrDiff(standardMatnr1, aufnrDiffList, standardMatnr.getParentUse() * parentuse);
        }
    }

    public void AddtoList(List<AufnrDiff> aufnrDiffList, AufnrDiff aufnrDiff, boolean adduse) {
        boolean bExist = false;
        for (AufnrDiff aufnrDiff1 : aufnrDiffList) {
            if (aufnrDiff.matnr.equals("28800002400600")) {
                logger.info("Debug");
            }
            //if (aufnrDiff.costcenter.equals(aufnrDiff1.costcenter) &&
            //        aufnrDiff.matnr.equals(aufnrDiff1.matnr)) {
            if (aufnrDiff.matnr.equals(aufnrDiff1.matnr)){

                //double totaluse = aufnrDiff.bomuse + aufnrDiff1.bomuse;
                double totaluse = aufnrDiff1.bomuse;
                if (adduse) {
                    totaluse = aufnrDiff.bomuse + aufnrDiff1.bomuse;
                }
                aufnrDiff1.laborCalculate.mergeStd(aufnrDiff.laborCalculate, adduse);
                aufnrDiff1.zjCalculate.mergeStd(aufnrDiff.zjCalculate, adduse);
                aufnrDiff1.rdCalculate.mergeStd(aufnrDiff.rdCalculate, adduse);
                aufnrDiff1.flCalculate.mergeStd(aufnrDiff.flCalculate, adduse);
                aufnrDiff1.qtCalculate.mergeStd(aufnrDiff.qtCalculate, adduse);
                aufnrDiff1.bomuse = totaluse;
                aufnrDiff1.stdChilds.add(aufnrDiff);
                aufnrDiff1.Cal();

                bExist = true;
                break;
            }
        }
        if (!bExist) {
            aufnrDiffList.add(aufnrDiff);
        }
    }

    public void CombinMaterialDiff(List<ZcorcMaterialDiff> realMaterialDiff, List<ZcorcMaterialDiff> stdMaterialDiff) {
        for (ZcorcMaterialDiff smd : stdMaterialDiff) {
            if(smd.getMatnr().equals("42010040003800")){
                logger.info("debug");
            }
            boolean bExist = false;
            for (ZcorcMaterialDiff rmd : realMaterialDiff) {
                if (smd.matnr.equals(rmd.matnr)) {
                    rmd.standarduse = smd.standarduse;
                    rmd.standardcost = smd.standardcost;
                    for (String key : smd.stdmap.keySet()) {
                        rmd.stdmap.put(key, smd.stdmap.get(key));
                    }
                    //rmd.stdmap = smd.stdmap;
                    rmd.Cal();
                    bExist = true;
                    break;
                }
            }
            //标准有，实际没有的物料
            if (!bExist) {
                smd.Cal();
                realMaterialDiff.add(smd);
            }
        }

        //实际有，标准没有的物料
        for (ZcorcMaterialDiff rmd : realMaterialDiff) {
            if (rmd.standarduse == 0) {
                rmd.standardcost = rmd.realcost;
                rmd.Cal();
            }
        }

        for (ZcorcMaterialDiff materialDiff : realMaterialDiff) {
            fillMaterialTree(materialDiff);
            //if (materialDiff.stdmap.size() > 0 && materialDiff.childs.size() > 0) {
            FindReason(materialDiff);
            // }
        }

        //找替换关系
        //FindMaterialReason(realMaterialDiff);

        //把剩下的都归类为尾差
        for (ZcorcMaterialDiff materialDiff : realMaterialDiff) {
            if (materialDiff.code == null) {
                if (materialDiff.numdiff < 0.1 && materialDiff.numdiff != 0) {
                    materialDiff.code = "1199";
                    materialDiff.reason = getReason(materialDiff.code);
                }
            }
        }
    }

    public void FindReason(ZcorcMaterialDiff materialDiff) {
        //判断物料标准用量和实际用量不一样的原因,量差
        if (Math.abs(materialDiff.standarduse - materialDiff.realuse) > 0.01) {
                double numdiff = materialDiff.standarduse - materialDiff.realuse;
                if (materialDiff.matnr == null || materialDiff.productname == null) {
                    return;
                }
                if (materialDiff.hiveSapZcorc != null) {
                    materialDiff.code = "1199";
                    materialDiff.reason = getReason(materialDiff.code);
                } else {
                    materialDiff.code = "1199";
                    materialDiff.reason = getReason(materialDiff.code);
                }
                if(mapZtmmx004.containsKey(materialDiff.getMatnr())){
                    List<AppSceneCostSapZtmmx004> list=mapZtmmx004.get(materialDiff.getMatnr());
                    for (AppSceneCostSapZtmmx004 ztmmx004:list){
                        String txt1 = ztmmx004.getZyylbA09();
                        String txt2 = ztmmx004.getZyylbA10();
                        String txt = txt1+txt2;
                        if(txt.contains("设计更改超领")){
                            materialDiff.code = "1101";
                            materialDiff.reason = getReason(materialDiff.code);
                        }
                        if(txt.contains("过程不良超领")){
                            materialDiff.code = "1102";
                            materialDiff.reason = getReason(materialDiff.code);
                        }
                        if(txt.contains("制程损耗超领")){
                            materialDiff.code = "1103";
                            materialDiff.reason = getReason(materialDiff.code);
                        }
                        if(txt.contains("拉力试验超领")){
                            materialDiff.code = "1104";
                            materialDiff.reason = getReason(materialDiff.code);
                        }
                        if(txt.contains("设备调度超领")){
                            materialDiff.code = "1105";
                            materialDiff.reason = getReason(materialDiff.code);
                        }
                        if(txt.contains("设计更改超领")){
                            materialDiff.code = "1101";
                            materialDiff.reason = getReason(materialDiff.code);
                        }
                    }
                }
        }
        if (Math.abs(materialDiff.standardcost - materialDiff.realcost) > 0.01) {
            //价格不一样,去采购记录里面找价格变更记录
            if (materialDiff.realuse > 0) {
                //外协件
                String ebeln = materialDiff.hiveSapZcorc.ebeln;

                if (ebeln != null && ebeln.trim().length() > 0) {
                    materialDiff.pricecode = "2102";
                    materialDiff.pricereason = getReason(materialDiff.pricecode);
                } else {
                    materialDiff.pricecode = "2101";
                    materialDiff.pricereason = getReason(materialDiff.pricecode);
                }
            }
        }
    }

    public AppSceneCostMaterial getMaterial(String matnr) {
        try {
            if (materialMap.containsKey(matnr)) {
                return materialMap.get(matnr);
            } else {
                QueryWrapper<AppSceneCostMaterial> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("material_number", matnr);
                List<AppSceneCostMaterial> materialList = iAppSceneCostMaterialService.list(queryWrapper);
                //MaterialExample example = new MaterialExample();
                //MaterialExample.Criteria criteria = example.createCriteria();
                //criteria.andMaterialNumberEqualTo(matnr);
                //List<Material> materialList = materialMapper.selectByExample(example);
                if (materialList.size() > 0) {
                    materialMap.put(matnr, materialList.get(0));
                    return materialList.get(0);
                }
                logger.info("Cannot find material " + matnr);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void fillMaterialTree(ZcorcMaterialDiff materialDiff) {
        AppSceneCostMaterial material1 = getMaterial(materialDiff.matnr);
        if (materialDiff.hiveSapZcorc != null) {
            materialDiff.productname = materialDiff.hiveSapZcorc.productname;
        }
        //materialDiff.productname=materialDiff.hiveSapZcorc.productname;
        if (material1 != null) {
            if (materialDiff.productname == null) {
                materialDiff.productname = material1.getProductName();
            } else if (materialDiff.productname.equals("")) {
                materialDiff.productname = material1.getProductName();
            }
            //materialDiff.productname = material1.getProductName();
            materialDiff.productcategory = material1.getProductCategory();
            materialDiff.materialtype = material1.getMaterialType();
            materialDiff.graphicnumber = material1.getGraphNumber();
        }
    }

    public void CheckStdMaterial(StandardMatnr standardMatnr, int resultindex) {
        double price_e = standardMatnr.accu_stage.price;
        double childprice = 0;
        for (StandardMatnr standardMatnr1 : standardMatnr.childs) {
            double price_e1 = standardMatnr1.stage.price + standardMatnr1.accu_stage.price;
            if (standardMatnr1.accu_stage.price > 0) {
                CheckStdMaterial(standardMatnr1, resultindex);
            }
            //ZcorcAufnr nodeAufnr = zcorcAufnrMap.get(layer);
            //CheckProductPriceAufnr(nodeAufnr, resultindex);
            if (standardMatnr1.standardBom == null || standardMatnr1.standardBom.getMenge() == null) {
                logger.info("debug");
            }
            childprice += price_e1 * standardMatnr1.standardBom.getMenge().doubleValue();
        }
        //childprice += standardMatnr.stage.price;
        if (Math.abs(childprice - price_e) > 1) {
            logger.info("标准物料制费不等：" + standardMatnr.layer);
        }
    }

    public void generateZcorcMaterialDiff(StandardMatnr standardMatnr, List<ZcorcMaterialDiff> materialDiffList, double parentuse, Map<String, AppSceneCostMaterial> materialMap) {
        if (standardMatnr.stage.price > 0) {
            ZcorcMaterialDiff materialDiff = new ZcorcMaterialDiff(standardMatnr, parentuse);
            if (materialDiff.matnr.equals("02020010001800")) {
                logger.info("Debug");
            }
            //materialDiff.standarduse *= parentuse;
            if (materialMap.containsKey(materialDiff.matnr)) {
                AppSceneCostMaterial material = materialMap.get(materialDiff.matnr);
                materialDiff.productname = material.getProductName();
                materialDiff.graphicnumber = material.getGraphNumber();
                materialDiff.productcategory = material.getProductCategory();
                materialDiff.oldMaterialGroup = material.getOldMaterialGroup();
                materialDiff.materialtype = material.getMaterialType();
            }
            AddtoList(materialDiffList, materialDiff);
        }

        for (StandardMatnr standardMatnr1 : standardMatnr.childs) {
            generateZcorcMaterialDiff(standardMatnr1, materialDiffList, standardMatnr.getParentUse() * parentuse, materialMap);
        }
    }

    public void AddtoList(List<ZcorcMaterialDiff> materialDiffList, ZcorcMaterialDiff materialDiff) {
        if(materialDiff.matnr.equals("02020010001800")){
            logger.info("02020010001800");
        }
        boolean bExist = false;
        for (ZcorcMaterialDiff materialDiff1 : materialDiffList) {
            if (materialDiff.matnr.equals(materialDiff1.matnr)) {
                double totaluse = materialDiff1.standarduse + materialDiff.standarduse;
                double total = materialDiff1.standarduse * materialDiff1.standardcost + materialDiff.standarduse * materialDiff.standardcost;
                materialDiff1.standarduse = totaluse;
                if (totaluse != 0) {
                    materialDiff1.standardcost = total / totaluse;
                } else {
                    materialDiff1.standardcost = 0;
                }
                //materialDiff1.standardcost = total / totaluse;
                bExist = true;
                break;
            }
        }
        if (!bExist) {
            materialDiffList.add(materialDiff);
        }
    }


    public Map<String, AppSceneCostMaterial> getVersionMaterialMap(String version) {
        Map<String, AppSceneCostMaterial> materialMap = new HashMap<>();
        if (versionTmpMap.containsKey(version)) {
            materialMap = versionTmpMap.get(version).materialMap;
        }
        return materialMap;
    }

    public TotalDiff getTotalDiff(ZcorcProduct product, StandardMatnr standardMatnr) {
        TotalDiff totalDiff = new TotalDiff();
        totalDiff.realtotal = 0;
        totalDiff.realmaterial = 0;
        totalDiff.reallabor = 0;
        totalDiff.realproduct = 0;
        double ppsmng = 0;
        for (ZcorcAufnr zcorcAufnr : product.nodeAufnrs) {
            HiveSapZcorc hiveSapZcorc = zcorcAufnr.hiveSapZcorc;
            totalDiff.matnr = hiveSapZcorc.matnr;
            //totalDiff.version = product.stageAccumulatedCost.getVersionNumber();
            totalDiff.aufnr = hiveSapZcorc.aufnr;
            totalDiff.wbs = hiveSapZcorc.ps_psp_pnr;
            totalDiff.werks = hiveSapZcorc.werks;
            //totalDiff.layer = hiveSapZcorc.layer;
            totalDiff.ymonth = hiveSapZcorc.ymonth;

            ppsmng += hiveSapZcorc.ppsmng;
            totalDiff.realtotal += hiveSapZcorc.rkst000;
            totalDiff.realmaterial += hiveSapZcorc.rkst001;
            totalDiff.reallabor += hiveSapZcorc.kst003 * hiveSapZcorc.ppsmng;
            totalDiff.realproduct += hiveSapZcorc.kst005 * hiveSapZcorc.ppsmng;
        }
        if (ppsmng > 0) {
            totalDiff.realtotal = totalDiff.realtotal / ppsmng;
            totalDiff.realmaterial = totalDiff.realmaterial / ppsmng;
            totalDiff.reallabor = totalDiff.reallabor / ppsmng;
            totalDiff.realproduct = totalDiff.realproduct / ppsmng;
        }

        if (standardMatnr != null) {
            totalDiff.version = standardMatnr.version;
            if (standardMatnr.standardResult == null || standardMatnr.standardResult.getTotalStandardCost() == null) {
                totalDiff.stdtotal = 0;
            } else {
                totalDiff.stdtotal = standardMatnr.standardResult.getTotalStandardCost().doubleValue();
            }
            totalDiff.stdlabor = standardMatnr.stage.labor + standardMatnr.accu_stage.labor;
            totalDiff.stdmaterial = standardMatnr.stage.price + standardMatnr.accu_stage.price;
            totalDiff.stdproduct = totalDiff.stdtotal - totalDiff.stdlabor - totalDiff.stdmaterial;
        }
        return totalDiff;
    }

    public String getReason(String code) {
        if (miningReasonMap.containsKey(code)) {
            return miningReasonMap.get(code).getReason();
        }
        return "";
    }

    public void AddOtherDiff(ZcorcProduct nodeProduct, TotalDiff totalDiff) {
        for (ZcorcAufnr zcorcAufnr : nodeProduct.nodeAufnrs) {
            //if (nodeProduct.nodeAufnr != null && nodeProduct.nodeAufnr.hiveSapZcorc != null) {
            HiveSapZcorc hiveSapZcorc = zcorcAufnr.hiveSapZcorc;
        }
    }

    public void CalculateReason(TotalDiff totalDiff, List<ZcorcMaterialDiff> materialDiffList, List<ZcorcAufnrDiff> aufnrDiffList) {
        Map<String, DiffReason> diffReasonMap = new HashedMap();
        for (ZcorcMaterialDiff materialDiff : materialDiffList) {
            if (materialDiff.code != null && materialDiff.code.length() > 0) {
                if (diffReasonMap.containsKey(materialDiff.code)) {
                    diffReasonMap.get(materialDiff.code).value += materialDiff.numdiff;
                } else {
                    DiffReason diffReason = new DiffReason();
                    diffReason.code = materialDiff.code;
                    diffReason.value = materialDiff.numdiff;
                    diffReason.reason = materialDiff.reason;
                    diffReasonMap.put(diffReason.code, diffReason);
                }
            }
            if (materialDiff.pricecode != null && materialDiff.pricecode.length() > 0) {
                if (diffReasonMap.containsKey(materialDiff.pricecode)) {
                    diffReasonMap.get(materialDiff.pricecode).value += materialDiff.pricediff;
                } else {
                    DiffReason diffReason = new DiffReason();
                    diffReason.code = materialDiff.pricecode;
                    diffReason.value = materialDiff.pricediff;
                    diffReason.reason = materialDiff.pricereason;
                    diffReasonMap.put(diffReason.code, diffReason);
                }
            }
        }
        double totaldiffvalue = 0;
        for (DiffReason diffReason : diffReasonMap.values()) {
            totalDiff.materialDiff.add(diffReason);
            totaldiffvalue += diffReason.value;
        }

        Map<String, DiffReason> lalbordiffReasonMapLabor = new HashedMap();
        Map<String, DiffReason> productdiffReasonMapLabor = new HashedMap();
        for (ZcorcAufnrDiff aufnrDiff : aufnrDiffList) {
            if (aufnrDiff.laborcode != null && aufnrDiff.laborcode.length() > 0) {
                if (lalbordiffReasonMapLabor.containsKey(aufnrDiff.laborcode)) {
                    lalbordiffReasonMapLabor.get(aufnrDiff.laborcode).value += aufnrDiff.getLaborDiff();
                } else {
                    DiffReason diffReason = new DiffReason();
                    diffReason.code = aufnrDiff.laborcode;
                    diffReason.value = aufnrDiff.getLaborDiff();
                    diffReason.reason = aufnrDiff.laborreason;
                    lalbordiffReasonMapLabor.put(diffReason.code, diffReason);
                }
            }

            if (aufnrDiff.productcode != null && aufnrDiff.productcode.length() > 0) {
                if (productdiffReasonMapLabor.containsKey(aufnrDiff.productcode)) {
                    productdiffReasonMapLabor.get(aufnrDiff.productcode).value += aufnrDiff.getProductDiff();
                } else {
                    DiffReason diffReason = new DiffReason();
                    diffReason.code = aufnrDiff.productcode;
                    diffReason.value = aufnrDiff.getProductDiff();
                    diffReason.reason = aufnrDiff.productreason;
                    productdiffReasonMapLabor.put(diffReason.code, diffReason);
                }
            }
        }
        for (DiffReason diffReason : lalbordiffReasonMapLabor.values()) {
            totalDiff.laborDiff.add(diffReason);
            totaldiffvalue += diffReason.value;
        }

        for (DiffReason diffReason : productdiffReasonMapLabor.values()) {
            totalDiff.productDiff.add(diffReason);
            totaldiffvalue += diffReason.value;
        }

        if (Math.abs(totaldiffvalue - totalDiff.stdtotal - totalDiff.realtotal) > 1) {
            logger.info("Total diff:" + totaldiffvalue);
        }
    }

    public void AddMiningZcorcMaterial(AppSceneCostMiningResult miningResultWithBLOBs, List<ZcorcMaterialDiff> materialDiffList, TotalDiff totalDiff, int resultindex) {
        //try {
        Gson gson = new Gson();
        double diff = totalDiff.realmaterial - totalDiff.stdmaterial;
        //List<MiningMaterial> miningMaterials=new ArrayList<>();
        int index = 0;
        for (ZcorcMaterialDiff materialDetail : materialDiffList) {
            index++;
            //logger.info("AddMiningZcorcMaterial:"+index+"/"+materialDiffList.size()+" childs:"+)
            AppSceneCostMiningMaterial miningMaterial = new AppSceneCostMiningMaterial();
            miningMaterial.setMatnr(materialDetail.matnr);
            miningMaterial.setResultid(resultindex);
            miningMaterial.setAufnr(miningResultWithBLOBs.getAufnr());
            miningMaterial.setVersion(miningResultWithBLOBs.getVersion());

//            if(materialDetailMap.containsKey(materialDetail.matnr)){
//                logger.info("AddMiningZcorcMaterial:"+index+"/"+materialDiffList.size()+" childs:"+materialDetailMap.get(materialDetail.matnr).size());
//                for (ZcorcMaterialDiff miningDiff : materialDetailMap.get(materialDetail.matnr)) {
//                    AddMiningMaterialDetail(miningDiff, resultindex);
//                }
//            }


            //MaterialDiff newitem=new MaterialDiff();
            //BeanUtils.copyProperties(materialDetail,newitem);
            //MaterialDiff newitem = gson.fromJson(gson.toJson(materialDetail), MaterialDiff.class);
            //newitem.childs.clear();
            //materialDetail.childs.clear();
            try {
                miningMaterial.setJsondata(gson.toJson(materialDetail));
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
            miningMaterial.setTotaldiff(new BigDecimal(materialDetail.totaldiff));
            if (diff != 0) {
                miningMaterial.setRatio(new BigDecimal(Math.abs(materialDetail.totaldiff / diff)));
            } else {
                miningMaterial.setRatio(new BigDecimal(0));
            }
            iAppSceneCostMiningMaterialService.save(miningMaterial);
            //miningMaterials.add(miningMaterial);
            //miningMaterialMapper.insert(miningMaterial);
            //amqpService.SendMessage("mining-material", gson.toJson(miningMaterial));
            //for (MaterialDiff miningDiff : materialDetail.childs) {
            //    AddMiningMaterialDetail(miningResultWithBLOBs, miningDiff, resultindex);
            //}
        }
        // } catch (Exception e) {
        //     logger.info(e.getMessage());
        // }
    }

    public void ClearCach(String version) {
        if (versionTmpMap.containsKey(version)) {
            versionTmpMap.remove(version);
        }
//        bomMap.clear();
//        productMap.clear();
//        materialMap.clear();
//        companyCostMap.clear();
//        purchaseRecordMap.clear();
//        latestPurchasePriceMap.clear();
//        c7525costMap.clear();
//        taxesMap.clear();
    }

    public void AddMingLog(int level, String content, int resultindex) {
        logger.info(content);
        //miningService.AddMiningLogToMQ(level,content,resultindex);
    }

    public void CancelMiningResult(String werks, String matnr, String posid, String version, String err) {
//        try {
//
//            MiningResultExample example = new MiningResultExample();
//            MiningResultExample.Criteria criteria = example.createCriteria();
//            criteria.andWerksEqualTo(werks);
//            criteria.andMatnrEqualTo(matnr);
//            //criteria.andAufnrEqualTo(aufnr);
//            criteria.andWbsEqualTo(posid);
//            criteria.andVersionEqualTo(version);
//            criteria.andStatusNotEqualTo("已完成");
//            List<MiningResult> miningResultList = miningResultMapper.selectByExample(example);
//            for (AppSceneCostMiningResult miningResult : miningResultList) {
//                miningResult.setStatus("已中止");
//                if (err == null) {
//                    err = "";
//                }
//                if (err.length() > 255) {
//                    err = err.substring(0, 250);
//                }
//                miningResult.setErr(err);
//                //miningResult.setLabordetail("");
//                //miningResult.setMdetail("");
//                miningResultMapper.updateByPrimaryKey(miningResult);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    public void AddZcorcMiningAufnr(AppSceneCostMiningResult miningResultWithBLOBs, List<ZcorcAufnrDiff> aufnrDiffList, TotalDiff totalDiff, int resultindex) {
        try {
            Gson gson = new Gson();
            double ldiff = totalDiff.reallabor - totalDiff.stdlabor;
            double pdiff = totalDiff.realproduct - totalDiff.stdproduct;
            int index = 0;
            for (ZcorcAufnrDiff aufnrDiff : aufnrDiffList) {
                index++;
                //logger.info("AddMiningAufnr " + index + "/" + aufnrDiffList.size());
                AppSceneCostMiningAufnr miningAufnr = new AppSceneCostMiningAufnr();
                miningAufnr.setResultid(resultindex);
                miningAufnr.setMatnr(aufnrDiff.matnr);
                miningAufnr.setBudat(aufnrDiff.budat);
                miningAufnr.setAufnr(miningResultWithBLOBs.getAufnr());
                miningAufnr.setVersion(miningResultWithBLOBs.getVersion());
                miningAufnr.setCostcenter(aufnrDiff.costcenter);

                if (aufnrDiff.totalcostlabor > 0) {
                    //miningAufnr.setRealchildcount(1);
                } else {
                    //miningAufnr.setRealchildcount(0);
                }
                //miningAufnr.setRealchildcount(1);
                //miningAufnr.setRealchildcount(aufnrDiff.realChilds.size());
                //aufnrDiff.stdChilds.clear();
                //aufnrDiff.realChilds.clear();
                miningAufnr.setJsondata(gson.toJson(aufnrDiff));
                miningAufnr.setLabordiff(new BigDecimal(aufnrDiff.laborCalculate.totaldiff));
                miningAufnr.setProductdiff(new BigDecimal(aufnrDiff.getProductDiff()));
                if (ldiff != 0) {
                    miningAufnr.setLaborratio(new BigDecimal(Math.abs(aufnrDiff.laborCalculate.totaldiff / ldiff)));
                } else {
                    miningAufnr.setLaborratio(new BigDecimal(0));
                }
                if (pdiff != 0) {
                    miningAufnr.setProductratio(new BigDecimal(Math.abs(aufnrDiff.getProductDiff() / pdiff)));
                } else {
                    miningAufnr.setProductratio(new BigDecimal(0));
                }

                iAppSceneCostMiningAufnrService.save(miningAufnr);

                //miningAufnrMapper.insert(miningAufnr);
                //amqpService.SendMessage("mining-aufnr", gson.toJson(miningAufnr));


                //}
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
    }

    public void AddMiningDiff(TotalDiff totalDiff, int resultindex) {
        try {
            for (DiffReason diffReason : totalDiff.materialDiff) {
                if (diffReason.value == 0) {
                    continue;
                }
                AppSceneCostMiningDiff miningDiff = new AppSceneCostMiningDiff();
                miningDiff.setValue(diffReason.value);
                miningDiff.setCode(diffReason.code);
                miningDiff.setReason(diffReason.reason);
                miningDiff.setType("material");
                miningDiff.setResultid(resultindex);
                //miningDiffMapper.insert(miningDiff);
                iAppSceneCostMiningDiffService.save(miningDiff);
            }

            for (DiffReason diffReason : totalDiff.laborDiff) {
                if (diffReason.value == 0) {
                    continue;
                }
                AppSceneCostMiningDiff miningDiff = new AppSceneCostMiningDiff();
                miningDiff.setValue(diffReason.value);
                miningDiff.setCode(diffReason.code);
                miningDiff.setReason(diffReason.reason);
                miningDiff.setType("labor");
                miningDiff.setResultid(resultindex);
                //miningDiffMapper.insert(miningDiff);
                iAppSceneCostMiningDiffService.save(miningDiff);
            }

            for (DiffReason diffReason : totalDiff.productDiff) {
                if (diffReason.value == 0) {
                    continue;
                }
                AppSceneCostMiningDiff miningDiff = new AppSceneCostMiningDiff();
                miningDiff.setValue(diffReason.value);
                miningDiff.setCode(diffReason.code);
                miningDiff.setReason(diffReason.reason);
                miningDiff.setType("product");
                miningDiff.setResultid(resultindex);
                //miningDiffMapper.insert(miningDiff);
                iAppSceneCostMiningDiffService.save(miningDiff);
            }

            for (DiffReason diffReason : totalDiff.otherDiff) {
                AppSceneCostMiningDiff miningDiff = new AppSceneCostMiningDiff();
                miningDiff.setValue(diffReason.value);
                miningDiff.setCode(diffReason.code);
                miningDiff.setReason(diffReason.reason);
                miningDiff.setType("other");
                miningDiff.setResultid(resultindex);
                //miningDiffMapper.insert(miningDiff);
                iAppSceneCostMiningDiffService.save(miningDiff);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
    }
}
