package com.steerinfo.ems.trmworkprocproductvalue.service.impl;

import com.steerinfo.ems.formula.model.Formula;
import com.steerinfo.ems.formula.service.IFormulaService;
import com.steerinfo.ems.trmworkprocproduct.model.TRmWorkprocProduct;
import com.steerinfo.framework.mapper.IBaseMapper;
import com.steerinfo.framework.service.impl.BaseServiceImpl;
import com.steerinfo.ems.trmworkprocproductvalue.model.TRmWorkprocProductValue;
import com.steerinfo.ems.Utils.BigDecimalUtil;
import com.steerinfo.ems.Utils.DateUtils;
import com.steerinfo.ems.common.DateTypeEnum;
import com.steerinfo.ems.ifmesemsproductorder.model.IfMesEmsProductorder;
import com.steerinfo.ems.ifmesemsproductorder.service.IIfMesEmsProductorderService;
import com.steerinfo.ems.ifmesemsswapfile.model.IfMesEmsSwapfile;
import com.steerinfo.ems.ifmesemsswapfile.service.IIfMesEmsSwapfileService;
import com.steerinfo.ems.trmproduct.mapper.TRmProductMapper;
import com.steerinfo.ems.trmproduct.model.TRmProduct;
import com.steerinfo.ems.trmproduct.service.ITRmProductService;
import com.steerinfo.ems.trmworkproc.model.TRmWorkproc;
import com.steerinfo.ems.trmworkproc.service.ITRmWorkprocService;
import com.steerinfo.ems.trmworkprocproduct.service.ITRmWorkprocProductService;
import com.steerinfo.ems.trmworkprocproductvalue.mapper.TRmWorkprocProductValueMapper;
import com.steerinfo.ems.trmworkprocproductvalue.service.ITRmWorkprocProductValueService;
import com.steerinfo.framework.service.pagehelper.PageHelper;
import com.steerinfo.framework.service.pagehelper.PageList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * TRmWorkprocProductValue服务实现：
 * @author generator
 * @version 1.0-SNAPSHORT 2019-10-17 04:31
 * 类描述
 * 修订历史：
 * 日期：2019-10-17
 * 作者：generator
 * 参考：
 * 描述：TRmWorkprocProductValue服务实现
 * @see null
 * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
 */
@Service(value = "tRmWorkprocProductValueService")
public class TRmWorkprocProductValueServiceImpl extends BaseServiceImpl<TRmWorkprocProductValue, HashMap<String, Object>> implements ITRmWorkprocProductValueService {

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

    @Autowired
    private TRmWorkprocProductValueMapper tRmWorkprocProductValueMapper;
    @Autowired
    IIfMesEmsSwapfileService ifMesEmsSwapfileService;
	@Autowired
    ITRmWorkprocProductService tRmWorkprocProductService;
	@Autowired
    IIfMesEmsProductorderService ifMesEmsProductorderService;
    @Autowired
    IFormulaService formulaService;
    @Autowired
    private TRmProductMapper tRmProductMapper;
    @Autowired
    ITRmProductService tRmProductService;
    @Autowired
    ITRmWorkprocService tRmWorkprocService;
    
    @Override
    protected IBaseMapper<TRmWorkprocProductValue, HashMap<String, Object>> getMapper() {
        return tRmWorkprocProductValueMapper;
    }

	@Override
	public TRmWorkprocProductValue updateForUKey(TRmWorkprocProductValue tRmWorkprocProductValue) {
		this.getMapper().updateByPrimaryKeySelective(tRmWorkprocProductValue);
		return tRmWorkprocProductValueMapper.selectByUPrimaryKey(tRmWorkprocProductValue);
	}

    @Override
    public PageList<Map<String, Object>> getWorkprocProductValueForPage(Map<String, Object> parameters, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<Map<String, Object>> workprocProductValues = tRmWorkprocProductValueMapper.getWorkprocProductValues(parameters);
        PageList<Map<String,Object>> pageInfo = new PageList<>(workprocProductValues);
        return pageInfo;
    }

    public int updateValue(HashMap<String, Object> m) {
		return tRmWorkprocProductValueMapper.updateValue(m);
	}

	public int insertValue(HashMap<String, Object> m) {
		return tRmWorkprocProductValueMapper.insertValue(m);
	}

	public int deleteByPrimaryKey(HashMap<String, Object> m) {
		return tRmWorkprocProductValueMapper.deleteByPrimaryKey(m);
	}

	/**
	 * 获取生产数据
	 * 将IF_MES_EMS_SWAPFILE中未读取的数据进行处理，将数据保存至 T_RM_WORKPROC_PRODUCT_VALUE
	 */
	public void synchronousData() {
		int success = 0;
		int failure = 0;
		int delSize = 0;
		int abandon = 0;
		HashMap<String, Object> selectObj = new HashMap<String, Object>();
		selectObj.put("type", "2");
		List<IfMesEmsSwapfile> list = ifMesEmsSwapfileService.selectNewMaterial(selectObj); // 获取未读取的产出数据
		for (int i = 0; i < list.size(); i++) {
			IfMesEmsSwapfile swapfile = list.get(i);
			// 找出需要修改的项
			if (swapfile.getStatus().equals("9")) {
				// 在T_RM_WORKPROC_PRODUCT中查找匹配的itemId
				HashMap<String, Object> itemObj = new HashMap<String, Object>();
				itemObj.put("mesMaterialcode", swapfile.getMaterialcode());
				itemObj.put("mesProdline", swapfile.getProdline());
				itemObj.put("itemtype", "R");
				List<TRmWorkprocProduct> relationItem = tRmWorkprocProductService.getMesItemid(itemObj);
				if (relationItem.size() == 1 && relationItem.get(0).getCode().equals("0")) {
					String itemid = relationItem.get(0).getItemid();
					// 更新数据项
					HashMap<String, Object> delObj = new HashMap<String, Object>();
					delObj.put("clock", DateUtils.dateToString(swapfile.getProdate(), "yyyy-MM-dd"));
					delObj.put("itemid", itemid);
					delObj.put("timegranid", "DAY");
					delObj.put("itemtype", "R");
					TRmWorkprocProductValue tRmWorkprocProductValue = tRmWorkprocProductValueMapper.selectByPrimaryKey(delObj);
					if (tRmWorkprocProductValue != null) {
						delSize++;
						logger.info("[更改][产出数据更改]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：T_RM_WORKPROC_PRODUCT_VALUE表中数据将要更新;");
						logger.info("将要更改的原数据项为：" + tRmWorkprocProductValue.toString());
						delObj.put("materialcode", relationItem.get(0).getMesMaterialcode());
                        delObj.put("prodline", relationItem.get(0).getMesProdline());
                        Map<String, Object> vl =  tRmWorkprocProductValueMapper.getItemval(delObj);
                        Double val = Double.valueOf(vl.get("VAL").toString());
                        String ids = vl.get("IDS")==null?"":vl.get("IDS").toString();
                        if(val>0){
                        	tRmWorkprocProductValue.setActualvalue(new BigDecimal(val));
                        	if(tRmWorkprocProductValue.getCorrectvalue()!=null){
                        		tRmWorkprocProductValue.setApportvalue(new BigDecimal(val).add(tRmWorkprocProductValue.getCorrectvalue()));
    						}else{
    							tRmWorkprocProductValue.setApportvalue(new BigDecimal(val));
    						}
                        	tRmWorkprocProductValue.setBz("MES-" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()) + " fid:" + ids);
                        	tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tRmWorkprocProductValue);
                        }else{
                        	tRmWorkprocProductValueMapper.deleteByPrimaryKey(delObj);
                        }
					}
				}
			}
		}
		for (int i = 0; i < list.size(); i++) {
			IfMesEmsSwapfile swapfile = list.get(i);
			// 在T_RM_WORKPROC_PRODUCT中查找匹配的itemId
			HashMap<String, Object> itemObj = new HashMap<String, Object>();
			itemObj.put("mesMaterialcode", swapfile.getMaterialcode());
			itemObj.put("mesProdline", swapfile.getProdline());
			itemObj.put("itemtype", "R");
			List<TRmWorkprocProduct> relationItem = tRmWorkprocProductService.getMesItemid(itemObj);
			if (relationItem.size() > 1) {
				failure++;
				logger.info("[错误][多条的关联项]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_SWAPFILE中 FID 为 " + swapfile.getFid() + " 的数据在T_RM_WORKPROC_PRODUCT中找到" + relationItem.size() + "条对应关系;( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )" );
				logger.info("关联项: ");
				for (int u = 0; u < relationItem.size(); u++) {
					logger.info(relationItem.get(u).getItemid()+";");
				}
			} else {
				TRmWorkprocProduct twp = new TRmWorkprocProduct();
				if(relationItem.size() == 1) {
					twp = relationItem.get(0);
				}else{
					logger.info("[错误][未找到关联项]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_SWAPFILE中 FID 为 " + swapfile.getFid() + " 的数据在T_RM_WORKPROC_PRODUCT中未找到对应关系;( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )，系统自动新增" );
					String bcode = swapfile.getMaterialcode(); // MES物料编码
					String mname = swapfile.getMaterialname(); // MES物料名称
					String mline = swapfile.getProdline(); // MES产线编码
					Map<String,Object> mp = new HashMap<String,Object>();
					mp.put("bcode", bcode);
					mp.put("name", mname);
					String pid = ""; // EMS产品ID
					List<TRmProduct> lp = tRmProductMapper.selectByParameters(mp);
					if (lp!=null && lp.size() >0){
						pid = lp.get(0).getId();
					} else {
						TRmProduct model = new TRmProduct();
						String maxId = tRmProductService.getMaxId();
				        maxId = String.format("%03d", Integer.parseInt(maxId) + 1);
				        model.setId("CP"+maxId);
				        model.setSeqno(maxId);
				        model.setName(mname);
				        model.setBcode(bcode);
				        model.setUnitid("008");
				        model.setRemark("MES自动新增");
				        model.setCreateman("系统");
				        model.setCreatetime(new Date());
				        model = tRmProductService.add(model);
				        pid = model.getId();
					}
					String itemid = ""; // 新增项目ID
					String itemidpr = ""; // 炼钢、轧钢主产品项目ID
					boolean addPr = false; // 是否添加到主产品（根据产品名称头判断）
					String wid = "";
//					if (mline.endsWith("BC1")) { // 棒材线
//						// MES工序与EMS工序没有关联，这里防止修改工序后造成数据错误，增加一次判断，下同
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY9101");
//						if(tw!=null && tw.getName().equalsIgnoreCase("棒材线")){
//							wid = "ZY9101";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY9101CP18R";
//							if (mname.startsWith("棒材︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("GX1")) { // 一高线
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY9102");
//						if(tw!=null && tw.getName().equalsIgnoreCase("一高线")){
//							wid = "ZY9102";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY9102CP19R";
//							if (mname.startsWith("一高线︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("GX2")) { // 二高线
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY9201");
//						if(tw!=null && tw.getName().equalsIgnoreCase("二高线")){
//							wid = "ZY9201";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY9201CP19R";
//							if (mname.startsWith("二高线︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("GX3")) { // 三高线
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY9103");
//						if(tw!=null && tw.getName().equalsIgnoreCase("三高线")){
//							wid = "ZY9103";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY9103CP19R";
//							if (mname.startsWith("三高线︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("GX4")) { // 四高线
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY9203");
//						if(tw!=null && tw.getName().equalsIgnoreCase("四高线")){
//							wid = "ZY9203";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY9203CP19R";
//							if (mname.startsWith("四高线︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("GX5")) { // 五高线
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY9204");
//						if(tw!=null && tw.getName().equalsIgnoreCase("五高线")){
//							wid = "ZY9204";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY9204CP19R";
//							if (mname.startsWith("五高线︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("GL3")) { // 二炼铁2#1280高炉-ZY7202
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY7202");
//						if(tw!=null && tw.getName().equalsIgnoreCase("二炼铁2#1280高炉")){
//							wid = "ZY7202";
//							itemid = wid + pid + "R";
//							itemidpr = "ZY7202CP14R";
//							if (mname.startsWith("二体系︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("LG1")) { // 一炼钢
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY8100");
//						if(tw!=null && tw.getName().equalsIgnoreCase("一炼钢")){
//							wid = "ZY8100";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY8100CP17R";
//							if (mname.startsWith("一体系︱")){
//								addPr = true;
//							}
//						}
//					} else if(mline.endsWith("LG2")) { // 二炼钢
//						TRmWorkproc tw = tRmWorkprocService.getById("ZY8200");
//						if(tw!=null && tw.getName().equalsIgnoreCase("二炼钢")){
//							wid = "ZY8200";
//							itemid = wid+ pid + "R";
//							itemidpr = "ZY8200CP17R";
//							if (mname.startsWith("二体系︱")){
//								addPr = true;
//							}
//						}
//					}
					if(!itemid.isEmpty() && !pid.isEmpty()){ // 更新 TRmWorkprocProduct，让其关联IF_MES_EMS_SWAPFILE数据（Mes_prodline、Mes_prodline）
						twp = tRmWorkprocProductService.getById(itemid);
						if (twp!=null){
							// 工序产品存在，更新产线数据
							if(twp.getMesProdline() == null || twp.getMesProdline().isEmpty()){
								twp.setMesProdline(mline);
								twp.setMesMaterialcode(bcode);
							} else {
								twp.setMesProdline(twp.getMesProdline() + "," + mline);
								twp.setMesMaterialcode(bcode);
							}
							twp = tRmWorkprocProductService.modify(twp);
						}else{
							// 工序产品不存在,新增
							twp = new TRmWorkprocProduct();
							twp.setId(itemid);
							twp.setMesMaterialcode(bcode);
							twp.setProductid(pid);
							twp.setWorkprocid(wid);
							twp.setUseflag("1");
							twp.setIsprimary("0");
							twp.setMesProdline(mline);
							twp.setCode("0");
							twp.setSeqno("10");
							twp.setItemtype("R");
							twp.setDigits(Short.valueOf("2"));
							twp.setUnitid("008"); // 单位：吨
							twp.setCreateman("系统");
							twp.setCreatetime(new Date());
							twp = tRmWorkprocProductService.add(twp);
							// 增加公式
							Formula formula = new Formula();
							formula.setClock("202001");
					        formula.setCode(itemid);
					        formula.setDescription(tRmWorkprocProductService.getName(itemid));
					        formula.setIsavailable("1");
					        formula.setRevisor("系统");
					        formula.setRevisetime(DateUtils.getCurrentTime("yyyy-MM-dd HH:mm:ss"));
					        formula.setSourcecode("R(T_RM_WORKPROC_PRODUCT_VALUE," + itemid + ")");
					        formula.setTablename("T_RM_WORKPROC_PRODUCT_VALUE");
					        formulaService.add(formula);
						}
						// 炼钢、轧钢，自动修改主产品公式
						if (addPr) {
							Formula f = formulaService.getFormulaLatest(itemidpr);
							if (f!=null && !f.getSourcecode().startsWith("R") && f.getSourcecode().indexOf(itemid) < 0) {
								f.setSourcecode(f.getSourcecode() + "+[" + itemid + "]");
								formulaService.updateFormula(f);
							}
						}
						logger.info("[新增成功]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：T_RM_WORKPROC_PRODUCT的itemid 为 " + itemid);
					} else {
						failure++;
						logger.info("[错误][新增失败]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_SWAPFILE中 FID 为 " + swapfile.getFid() + " 的数据在T_RM_WORKPROC_PRODUCT中未找到对应关系;( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )" );
						continue;
					}
				}
				if (twp.getCode()!=null && twp.getCode().equals("1")) {
                    abandon++;
                    logger.info("[放弃添加]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_SWAPFILE中 FID 为 " + swapfile.getFid() + " 的数据项被配置成由公式自动生成，所以放弃添加。( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )");
                    logger.info("关联项：" + twp.toString());
                } else if (twp.getCode()!=null && twp.getCode().equals("0")) {
                	// 数据添加至T_RM_WORKPROC_PRODUCT_VALUE
					HashMap<String, Object> insertObj = new HashMap<String, Object>();
					insertObj.put("clock", DateUtils.dateToString(swapfile.getProdate(), "yyyy-MM-dd"));
					insertObj.put("timegranid", "DAY");
					insertObj.put("itemid", twp.getItemid());
					insertObj.put("itemtype", "R");
					insertObj.put("qty", swapfile.getQty());
					insertObj.put("fid", swapfile.getFid());
					insertObj.put("userid", "系统");
					insertObj.put("updatetime", DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
					try {
						int upSize = tRmWorkprocProductValueMapper.updateValue(insertObj);
						if (upSize == 0) {
							tRmWorkprocProductValueMapper.insertValue(insertObj);
						}
						success++;
						// 反写IF_MES_EMS_SWAPFILE的status
						HashMap<String, Object> updateObj = new HashMap<String, Object>();
						updateObj.put("fid", swapfile.getFid());
						updateObj.put("status", "1");
						ifMesEmsSwapfileService.updateStatus(updateObj);
					} catch (Exception e) {
						failure++;
						logger.info("[错误][添加失败]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_SWAPFILE中 FID 为 " + swapfile.getFid() + " 的数据添加至T_RM_WORKPROC_PRODUCT_VALUE时失败;" );
						logger.info("添加失败的数据为：" + insertObj.toString());
						e.printStackTrace();
					}
					// 如果是昨天之前的数据，重新计算关联项数据
			        try {
			        	Date pdate = new SimpleDateFormat("yyyy-MM-dd").parse(swapfile.getProdate());
			        	Calendar calendar = Calendar.getInstance();
                    	calendar.add(Calendar.DAY_OF_YEAR, -1);
                    	Date yesterday = new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()));
                    	if(pdate.before(yesterday)){
                    		formulaService.reCalculate(twp.getItemid(), DateUtils.dateToString(swapfile.getProdate(), "yyyy-MM-dd"), "DAY", DateUtils.dateToString(swapfile.getProdate(), "yyyy-MM-dd"));
                    	}
			        } catch (Exception e) {
			        	e.printStackTrace();
			        }
                }
			}
		}
		logger.info("[产出数据添加完毕]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + "：数据添加成功" + success + "条(其中修改数据为" + delSize + "条)，放弃" + abandon + "条，失败" + failure + "条;");
	}

	/**
	 * 获取生产计划数据
	 * 将IF_MES_EMS_PRODUCTORDER中未读取的数据进行处理，将数据保存至T_RM_WORKPROC_PRODUCT_VALUE
	 */
	public void synchronousOrderData() {
		int success = 0;
		int failure = 0;
		int delSize = 0;
		int abandon = 0;
		HashMap<String, Object> selectObj = new HashMap<String, Object>();
		List<IfMesEmsProductorder> list = ifMesEmsProductorderService.selectNewMaterial(selectObj); // 获取未读取的产出数据
		for (int i = 0; i < list.size(); i++) {
			IfMesEmsProductorder swapfile = list.get(i);
			// 找出需要修改的项
			if (swapfile.getStatus().equals("9")) {
				// 在T_RM_WORKPROC_PRODUCT中查找匹配的itemId
				HashMap<String, Object> itemObj = new HashMap<String, Object>();
				itemObj.put("mesMaterialcode", swapfile.getMaterialcode());
				itemObj.put("mesProdline", swapfile.getProdline());
				itemObj.put("itemtype", "P");
				List<TRmWorkprocProduct> relationItem = tRmWorkprocProductService.getMesItemid(itemObj);
				if (relationItem.size() == 1 && relationItem.get(0).getCode().equals("0")) {
					String itemid = relationItem.get(0).getItemid();
					// 删除需要更新的数据项
					HashMap<String, Object> delObj = new HashMap<String, Object>();
					delObj.put("clock", DateUtils.dateToString(swapfile.getEprodate(), "yyyy-MM"));
					delObj.put("itemid", itemid);
					delObj.put("timegranid", "MONTH");
					delObj.put("itemtype", "P");
					TRmWorkprocProductValue tRmWorkprocProductValue = tRmWorkprocProductValueMapper.selectByPrimaryKey(delObj);
					if (tRmWorkprocProductValue != null) {
						delSize++;
						logger.info("[更改][产出数据更改]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：T_RM_WORKPROC_PRODUCT_VALUE表中数据将要更新;");
						logger.info("将要更改的原数据项为：" + tRmWorkprocProductValue.toString());
						delObj.put("materialcode", relationItem.get(0).getMesMaterialcode());
                        delObj.put("prodline", relationItem.get(0).getMesProdline());
                        Map<String, Object> vl =  tRmWorkprocProductValueMapper.getItempval(delObj);
                        Double val = (Double)vl.get("VAL");
                        String ids = vl.get("IDS")==null?"":vl.get("IDS").toString();
                        if(val>0){
                        	tRmWorkprocProductValue.setActualvalue(new BigDecimal(val));
                        	if(tRmWorkprocProductValue.getCorrectvalue()!=null){
                        		tRmWorkprocProductValue.setApportvalue(new BigDecimal(val).add(tRmWorkprocProductValue.getCorrectvalue()));
    						}else{
    							tRmWorkprocProductValue.setApportvalue(new BigDecimal(val));
    						}
                        	tRmWorkprocProductValue.setBz("MES-" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()) + " fid:" + ids);
                        	tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tRmWorkprocProductValue);
                        }else{
                        	tRmWorkprocProductValueMapper.deleteByPrimaryKey(delObj);
                        }
					}
				}
			}
		}
		for (int i = 0; i < list.size(); i++) {
			IfMesEmsProductorder swapfile = list.get(i);
			// 在T_RM_WORKPROC_PRODUCT中查找匹配的itemId
			HashMap<String, Object> itemObj = new HashMap<String, Object>();
			itemObj.put("mesMaterialcode", swapfile.getMaterialcode());
			itemObj.put("mesProdline", swapfile.getProdline());
			itemObj.put("itemtype", "P");
			List<TRmWorkprocProduct> relationItem = tRmWorkprocProductService.getMesItemid(itemObj);
			if (relationItem.size() > 1) {
				logger.info("[错误][多条的关联项]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_PRODUCTORDER中 FID 为 " + swapfile.getFid() + " 的数据在T_RM_WORKPROC_PRODUCT中找到" + relationItem.size() + "条对应关系;( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )" );
				logger.info("关联项：");
				for (int u = 0; u < relationItem.size(); u++) {
					logger.info(relationItem.get(u).getItemid()+";");
				}
			}else {
				TRmWorkprocProduct twp = new TRmWorkprocProduct();
				if(relationItem.size() == 1) {
					twp = relationItem.get(0);
				}else{
					logger.info("[错误][未找到关联项]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_PRODUCTORDER中 FID 为 " + swapfile.getFid() + " 的数据在T_RM_WORKPROC_PRODUCT中未找到对应关系;( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )，系统自动新增" );
					String bcode = swapfile.getMaterialcode(); // MES物料编码
					String mname = swapfile.getMaterialname(); // MES物料名称
					String mline = swapfile.getProdline(); // MES产线编码
					Map<String,Object> mp = new HashMap<String,Object>();
					mp.put("bcode", bcode);
					mp.put("name", mname);
					String pid = ""; // EMS产品ID
					List<TRmProduct> lp = tRmProductMapper.selectByParameters(mp);
					if (lp!=null && lp.size() >0){
						pid = lp.get(0).getId();
					} else {
						TRmProduct model = new TRmProduct();
						String maxId = tRmProductService.getMaxId();
				        maxId = String.format("%03d", Integer.parseInt(maxId) + 1);
				        model.setId("CP"+maxId);
				        model.setSeqno(maxId);
				        model.setName(mname);
				        model.setBcode(bcode);
				        model.setUnitid("008");
				        model.setRemark("MES自动新增");
				        model.setCreateman("系统");
				        model.setCreatetime(new Date());
				        model = tRmProductService.add(model);
				        pid = model.getId();
					}
					String itemid = "";
					String wid = "";
					if (mline.endsWith("BC1")) { // 棒材线
						// MES工序与EMS工序没有关联，这里防止修改工序后造成数据错误，增加一次判断，下同
						TRmWorkproc tw = tRmWorkprocService.getById("ZY9101");
						if(tw!=null && tw.getName().equalsIgnoreCase("棒材线")){
							wid = "ZY9101";
							itemid = wid+ pid + "P";
						}
					} else if(mline.endsWith("GX1")) { // 一高线-ZY9102
						TRmWorkproc tw = tRmWorkprocService.getById("ZY9102");
						if(tw!=null && tw.getName().equalsIgnoreCase("一高线")){
							wid = "ZY9102";
							itemid = wid+ pid + "P";
						}
					} else if(mline.endsWith("GX2")) { // 二高线
						TRmWorkproc tw = tRmWorkprocService.getById("ZY9201");
						if(tw!=null && tw.getName().equalsIgnoreCase("二高线")){
							wid = "ZY9201";
							itemid = wid+ pid + "P";
						}
					} else if(mline.endsWith("GX3")) { // 三高线
						TRmWorkproc tw = tRmWorkprocService.getById("ZY9103");
						if(tw!=null && tw.getName().equalsIgnoreCase("三高线")){
							wid = "ZY9103";
							itemid = wid+ pid + "P";
						}
					} else if(mline.endsWith("GX4") || mline.endsWith("GX5")) { // 四高线、五高线
						TRmWorkproc tw = tRmWorkprocService.getById("ZY9202");
						if(tw!=null && tw.getName().equalsIgnoreCase("四五高线")){
							wid = "ZY9202";
							itemid = wid+ pid + "P";
						}
					} else if(mline.endsWith("LG1")) { // 一炼钢
						TRmWorkproc tw = tRmWorkprocService.getById("ZY8100");
						if(tw!=null && tw.getName().equalsIgnoreCase("一炼钢")){
							wid = "ZY8100";
							itemid = wid+ pid + "P";
						}
					} else if(mline.endsWith("LG2")) { // 二炼钢
						TRmWorkproc tw = tRmWorkprocService.getById("ZY8200");
						if(tw!=null && tw.getName().equalsIgnoreCase("二炼钢")){
							wid = "ZY8200";
							itemid = wid+ pid + "P";
						}
					}
					if(!itemid.isEmpty() && !pid.isEmpty()){ // 更新 TRmWorkprocProduct，让其关联IF_MES_EMS_SWAPFILE数据（MesProdline、MesProdline）
						twp = tRmWorkprocProductService.getById(itemid);
						if (twp!=null){
							// 工序产品存在，更新产线数据
							if(twp.getMesProdline() == null || twp.getMesProdline().isEmpty()){
								twp.setMesProdline(mline);
								twp.setMesMaterialcode(bcode);
							} else {
								twp.setMesProdline(twp.getMesProdline() + "," + mline);
								twp.setMesMaterialcode(bcode);
							}
							twp = tRmWorkprocProductService.modify(twp);
						}else{
							// 工序产品不存在,新增
							twp = new TRmWorkprocProduct();
							twp.setId(itemid);
							twp.setMesMaterialcode(bcode);
							twp.setProductid(pid);
							twp.setWorkprocid(wid);
							twp.setUseflag("1");
							twp.setIsprimary("0");
							twp.setMesProdline(mline);
							twp.setCode("0");
							twp.setSeqno("10");
							twp.setItemtype("P");
							twp.setDigits(Short.valueOf("2"));
							twp.setUnitid("008"); // 单位：吨
							twp.setCreateman("系统");
							twp.setCreatetime(new Date());
							twp = tRmWorkprocProductService.add(twp);
							// 增加公式
							Formula formula = new Formula();
							formula.setClock("202001");
					        formula.setCode(itemid);
					        formula.setDescription(tRmWorkprocProductService.getName(itemid));
					        formula.setIsavailable("1");
					        formula.setRevisor("系统");
					        formula.setRevisetime(DateUtils.getCurrentTime("yyyy-MM-dd HH:mm:ss"));
					        formula.setSourcecode("R(T_RM_WORKPROC_PRODUCT_VALUE," + itemid + ")");
					        formula.setTablename("T_RM_WORKPROC_PRODUCT_VALUE");
					        formulaService.add(formula);
						}
					} else {
						failure++;
						logger.info("[错误][新增失败]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_PRODUCTORDER中 FID 为 " + swapfile.getFid() + " 的数据在T_RM_WORKPROC_PRODUCT中未找到对应关系;( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )" );
						continue;
					}
				}
				if (twp.getCode()!=null && twp.getCode().equals("1")) {
                    abandon++;
                    logger.info("[放弃添加]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_PRODUCTORDER中 FID 为 " + swapfile.getFid() + " 的数据项被配置成由公式自动生成，所以放弃添加。( MES物料编码:" + swapfile.getMaterialcode() + " ,MES物料名称:" + swapfile.getMaterialname() + " ,MES产线编码：" + swapfile.getProdline() + " )");
                    logger.info("关联项：" + twp.toString());
                } else if (twp.getCode()!=null && twp.getCode().equals("0")) {
                	// 数据添加至T_RM_WORKPROC_PRODUCT_VALUE
                	String clock = DateUtils.dateToString(swapfile.getEprodate(), "yyyy-MM");
					HashMap<String, Object> insertObj = new HashMap<String, Object>();
					insertObj.put("clock", clock);
					insertObj.put("timegranid", "MONTH");
					insertObj.put("itemid", twp.getItemid());
					insertObj.put("itemtype", "P");
					insertObj.put("qty", swapfile.getQty());
					insertObj.put("fid", swapfile.getFid());
					insertObj.put("userid", "1");
					insertObj.put("updatetime", DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
					try {
						int upSize = tRmWorkprocProductValueMapper.updateValue(insertObj);
						if (upSize == 0) {
							tRmWorkprocProductValueMapper.insertValue(insertObj);
						}
						success++;
						// 反写IF_MES_EMS_PRODUCTORDER的status
						HashMap<String, Object> updateObj = new HashMap<String, Object>();
						updateObj.put("fid", swapfile.getFid());
						updateObj.put("status", "1");
						ifMesEmsProductorderService.updateStatus(updateObj);
					} catch (Exception e) {
						failure++;
						logger.info("[错误][添加失败]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + " ：IF_MES_EMS_SWAPFILE中 FID 为 " + swapfile.getFid() + " 的数据添加至T_RM_WORKPROC_PRODUCT_VALUE时失败;" );
						logger.info("添加失败的数据为：" + insertObj.toString());
						e.printStackTrace();
					}
					// 如果是本月的数据，重新计算关联项数据
			        try {
			        	if(clock.equals(new SimpleDateFormat("yyyy-MM").format(new Date())) && !DateTypeEnum.getMethod("dm").getDate().equals("1")){
			        		formulaService.reCalculate(twp.getItemid(), clock, "MONTH", clock);
			        	}
			        } catch (Exception e) {
			        	logger.error("重新计算计划错误-itemid：" + twp.getItemid() + ",clock:" + clock);
			        	e.printStackTrace();
			        }
                }
			}
		}
		logger.info("[计划产出数据添加完毕]" + DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss") + "：数据添加成功" + success + "条(其中修改数据为" + delSize + "条)，放弃" + abandon + "条，失败" + failure + "条;");
	}

	@Override
	public PageList<Map<String, Object>> getDate53ForPage(HashMap<String, Object> parmas, Integer pageNum, Integer pageSize) {
		PageHelper.startPage(pageNum, pageSize);
        List<Map<String, Object>> rows = tRmWorkprocProductValueMapper.getDate53(parmas);
        PageList<Map<String, Object>> pageInfo = new PageList<Map<String, Object>>(rows);
        return pageInfo;
	}

	@Override
	public TRmWorkprocProductValue insert(TRmWorkprocProductValue t) {
		tRmWorkprocProductValueMapper.insert(t);
		return t;
	}

    @Override
    public Double getSumvalue(HashMap<String, Object> params) {
        return tRmWorkprocProductValueMapper.getSumvalue(params);
    }

    @Override
    public Set<String> getByCompositekeys() {
        return tRmWorkprocProductValueMapper.getByCompositekeys();
    }

    @Override
    public Double getTRmActValue(HashMap<String, Object> params) {
        return tRmWorkprocProductValueMapper.getTRmActValue(params);
    }

    @Override
    // @Transactional(rollbackFor = Exception.class)
    public void setDate(Date date) {
    	this.synchronousData();
    	//this.synchronousOrderData();
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
        // 获取项目信息-用于每日计算,包括实绩与计划
        List<TRmWorkprocProduct> models = tRmWorkprocProductService.getIdAndDigits("");
        for (TRmWorkprocProduct tp : models) {
        	String clock = "";
        	String type = tp.getItemtype();
        	// 日数据,只有code为1的实绩项目需要计算
        	HashMap<String, Object> id = new HashMap<String, Object>();
        	id.put("itemid", tp.getItemid());
        	id.put("itemtype", type);
        	if(tp.getCode().equals("1") && type.equalsIgnoreCase("R")) {
        		calendar.add(Calendar.DAY_OF_YEAR, -1);
	            clock = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
	            calendar.add(Calendar.DAY_OF_YEAR, 1);
            	id.put("clock", clock);
            	id.put("timegranid", "DAY");
            	// 获取原数据
            	TRmWorkprocProductValue tv = tRmWorkprocProductValueMapper.selectByPrimaryKey(id);
            	//获取计算值
                Double val= formulaService.getValByItemid(tp.getItemid(), "DAY", clock, 0);
                if(val<0){
                	val=0.0;
                    logger.info("id:"+tp.getItemid()+"计算错误");
                }
            	if(tv == null){
            		tv = new TRmWorkprocProductValue();
            		tv.setClock(clock);
            		tv.setItemid(tp.getItemid());
            		tv.setTimegranid("DAY");
            		tv.setItemtype(type);
                    tv.setActualvalue(new BigDecimal(val));
                    tv.setApportvalue(new BigDecimal(val));
                    tv.setCorrectvalue(BigDecimal.ZERO);
                    tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    this.insert(tv);
            	} else {
            		// 存在数据做更新
        			tv.setActualvalue(new BigDecimal(val));
        			if(tv.getCorrectvalue()!=null){
        				tv.setApportvalue(new BigDecimal(val).add(tv.getCorrectvalue()));
					}else{
						tv.setApportvalue(new BigDecimal(val));
					}
        			tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
        			tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tv);
            	}
        	}
        	// 月初统计上月实绩数据、统计本月计划（新增或者更新）
        	if(calendar.get(Calendar.DAY_OF_MONTH) <= 3) {
        		if(type.equalsIgnoreCase("P") && !tp.getCode().equals("1")){
        			// 非公式计划月数据由每日定时任务计算，这里不处理
        		} else {
        			if(type.equalsIgnoreCase("R")){
        				// 实绩统计上月
        				calendar.add(Calendar.MONTH, -1);
			            clock = new SimpleDateFormat("yyyy-MM").format(calendar.getTime());
			            calendar.add(Calendar.MONTH, 1);
            		}else{
            			// 计划统计本月
            			clock = DateUtils.dateStr(date, "yyyy-MM");
            		}
            		id.put("clock", clock);
            		id.put("timegranid", "MONTH");
        			// 获取原数据
            		TRmWorkprocProductValue tv = tRmWorkprocProductValueMapper.selectByPrimaryKey(id);
            		// 获取计算值
            		Double val = 0d;
        			// 实绩月数据为日数据之和
            		if(type.equalsIgnoreCase("R")){
            			val = this.getSumvalue(tp.getItemid(),clock,"DAY");
            		}else if(type.equalsIgnoreCase("P") && tp.getCode().equals("1")){
            			// 计划公式数据统计
            			val= formulaService.getValByItemid(tp.getItemid(), "MONTH", clock, 0);
            		}
            		if(tv == null){
            			tv = new TRmWorkprocProductValue();
                		tv.setClock(clock);
                		tv.setItemid(tp.getItemid());
                		tv.setTimegranid("MONTH");
                		tv.setItemtype(type);
                		tv.setActualvalue(new BigDecimal(val));
                        tv.setApportvalue(new BigDecimal(val));
                        tv.setCorrectvalue(BigDecimal.ZERO);
                        tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
                        this.insert(tv);
            		}else {
                		// 存在数据做更新
            			tv.setActualvalue(new BigDecimal(val));
            			if(tv.getCorrectvalue()!=null){
            				tv.setApportvalue(new BigDecimal(val).add(tv.getCorrectvalue()));
    					}else{
    						tv.setApportvalue(new BigDecimal(val));
    					}
            			tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
            			tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tv);
                	}
        		}
        	}
        	// 年初统计去年数据（新增或者更新）
        	if(calendar.get(Calendar.DAY_OF_YEAR) <= 5) {
        		calendar.add(Calendar.YEAR, -1);
	            clock = new SimpleDateFormat("yyyy").format(calendar.getTime());
	            calendar.add(Calendar.YEAR, 1);
        		id.put("clock", clock);
        		id.put("timegranid", "YEAR");
        		// 获取原数据
        		TRmWorkprocProductValue tv = tRmWorkprocProductValueMapper.selectByPrimaryKey(id);
        		// 年数据等于，月数据之和
        		Double val = this.getSumvalue(tp.getItemid(),clock,"MONTH");
        		if(tv == null){
        			tv = new TRmWorkprocProductValue();
            		tv.setClock(clock);
            		tv.setItemid(tp.getItemid());
            		tv.setTimegranid("YEAR");
            		tv.setItemtype(type);
            		tv.setActualvalue(new BigDecimal(val));
                    tv.setApportvalue(new BigDecimal(val));
                    tv.setCorrectvalue(BigDecimal.ZERO);
            		tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
            		this.insert(tv);
        		}else {
        			// 存在数据做更新
        			tv.setActualvalue(new BigDecimal(val));
        			if(tv.getCorrectvalue()!=null){
        				tv.setApportvalue(new BigDecimal(val).add(tv.getCorrectvalue()));
					}else{
						tv.setApportvalue(new BigDecimal(val));
					}
        			tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
        			tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tv);
            	}
        	}
        }
        logger.info("工序与产品定时任务结束（实绩与计划）.......");
    }

    @Override
    public Map<String, BigDecimal> getOutPut(HashMap<String, Object> params) {
        return tRmWorkprocProductValueMapper.getOutPut(params);
    }
    
    public Map<String,BigDecimal>getOutPut(String workprocid,String clock,String timegranid,String itemtype){
    	HashMap<String, Object> maps = new HashMap<>();
    	maps.put("workprocid", workprocid);
    	maps.put("clock", clock);
    	maps.put("timegranid", timegranid);
    	maps.put("itemtype", itemtype);
    	Map<String, BigDecimal> outPut = tRmWorkprocProductValueMapper.getOutPut(maps);
    	return outPut;
    }

    public Double getSumvalue(String itemid,String clock,String timegranid) {
        HashMap<String, Object> maps = new HashMap<>();
        maps.put("itemid", itemid);
        maps.put("clock", clock);
        maps.put("timegranid", timegranid);
        Double sumvalue = tRmWorkprocProductValueMapper.getSumvalue(maps);
        if (null == sumvalue) {
            return 0.0;
        }
        return sumvalue;
    }

	@Override
	public void createRData(String timegranid,String clock,String timegranidSource) {
		HashMap<String, Object> maps = new HashMap<>();
        maps.put("clock", clock);
        maps.put("timegranid", timegranidSource);
		List<String> itemids = tRmWorkprocProductValueMapper.selectItemidByClock(maps);
		for (int i = 0; i < itemids.size(); i++) {
			String itemid = itemids.get(i);
			this.restatData(itemid, clock, timegranid);
		}
	}

	@Override
	public String restatData(String itemid, String clock, String timegranid) {
		TRmWorkprocProduct twp = tRmWorkprocProductService.getById(itemid);
		Short digits = twp.getDigits() == null ? 2 : twp.getDigits();
		String code = twp.getCode();
		String mes_materialcode = twp.getMesMaterialcode();
		String mes_prodline = twp.getMesProdline();
		if (code.equals("0") && (mes_materialcode ==null || mes_prodline ==null || mes_materialcode.isEmpty() || mes_prodline.isEmpty())) {
			logger.info("产品[" + itemid + "]MES物料编码或者产线信息不完整");
			return "原料编码或者产线信息不完整";
		}
		try {
			if(timegranid.equalsIgnoreCase("DAY")){
				if(itemid.endsWith("P")) {
					return "产品计划值只计算月粒度以上";
				}else if(itemid.endsWith("R")) {
					HashMap<String, Object> hpm = new HashMap<String, Object>();
					hpm.put("clock", clock);
					hpm.put("itemid", itemid);
					hpm.put("timegranid", timegranid);
					hpm.put("itemtype", itemid.substring(itemid.length()-1, itemid.length()));
					hpm.put("materialcode", mes_materialcode);
					hpm.put("prodline", mes_prodline);
					// 计算值
		            Double actualvalue = 0d;
		            String ids = "";
					if(code.equals("0")){
		                Map<String, Object> vl =  tRmWorkprocProductValueMapper.getItemval(hpm);
		                actualvalue = new BigDecimal(vl.get("VAL").toString()).setScale(digits, RoundingMode.HALF_UP).doubleValue();
		                ids = vl.get("IDS")==null?"":vl.get("IDS").toString();
					}else if(code.equals("1")){
						// 公式计算型
						actualvalue = formulaService.getValByItemid(itemid, timegranid, clock, 0);
					}
	                // 获取原数据
	                TRmWorkprocProductValue tv = tRmWorkprocProductValueMapper.selectByPrimaryKey(hpm);
	                if(tv!=null && tv.getActualvalue().doubleValue() != actualvalue.doubleValue()){
	    				tv.setActualvalue(new BigDecimal(actualvalue));
	    	            tv.setApportvalue(BigDecimalUtil.add(tv.getCorrectvalue()!=null?tv.getCorrectvalue().doubleValue():0d, actualvalue).setScale(digits, RoundingMode.HALF_UP));
	    	            tv.setUptime(new Date());
	    	            if (!ids.isEmpty()){
	    	            	tv.setBz("MES-" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()) + " fid:" + ids);
	    	            }
	    	            tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tv);
	    			}else if(tv==null){
	    				tv = new TRmWorkprocProductValue();
	    				tv.setItemid(itemid);
	    				tv.setClock(clock);
	    				tv.setTimegranid(timegranid);
	    				tv.setItemtype(itemid.substring(itemid.length()-1, itemid.length()));
	    	            //计算值
	    				tv.setActualvalue(new BigDecimal(actualvalue).setScale(digits, RoundingMode.HALF_UP));
	    	            //修正值
	    				tv.setCorrectvalue(new BigDecimal(0));
	    	            //最终值
	    				tv.setApportvalue(new BigDecimal(actualvalue).setScale(digits, RoundingMode.HALF_UP));
	    				tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
	    				if (!ids.isEmpty()){
	    	            	tv.setBz("MES-" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()) + " fid:" + ids);
	    	            }
	    	            tRmWorkprocProductValueMapper.insert(tv);
	    			}
				}
			} else if((timegranid.equalsIgnoreCase("MONTH") || timegranid.equalsIgnoreCase("YEAR"))){
				// 计划产品月数据为MES数据计算或者公式计算，其他情况为低粒度累加
				if(itemid.endsWith("P") && timegranid.equalsIgnoreCase("MONTH")){
					HashMap<String, Object> hpm = new HashMap<String, Object>();
					hpm.put("clock", clock);
					hpm.put("itemid", itemid);
					hpm.put("timegranid", timegranid);
					hpm.put("itemtype", itemid.substring(itemid.length()-1, itemid.length()));
					hpm.put("materialcode", twp.getMesMaterialcode());
					hpm.put("prodline", twp.getMesMaterialcode());
					// 计算值
		            Double actualvalue = 0d;
		            String ids = "";
					if(code.equals("0")){
		                Map<String, Object> vl =  tRmWorkprocProductValueMapper.getItempval(hpm);
		                actualvalue = new BigDecimal(vl.get("VAL").toString()).setScale(digits, RoundingMode.HALF_UP).doubleValue();
		                ids = vl.get("IDS")==null?"":vl.get("IDS").toString();
					}else if(code.equals("1")){
						// 公式计算型
						actualvalue = formulaService.getValByItemid(itemid, timegranid, clock, 0);
					}
	                // 获取原数据
	                TRmWorkprocProductValue tv = tRmWorkprocProductValueMapper.selectByPrimaryKey(hpm);
	                if(tv!=null){
	    				tv.setActualvalue(new BigDecimal(actualvalue).setScale(digits, RoundingMode.HALF_UP));
	    	            tv.setApportvalue(BigDecimalUtil.add(tv.getCorrectvalue()!=null?tv.getCorrectvalue().doubleValue():0d, actualvalue).setScale(digits, RoundingMode.HALF_UP));
	    	            tv.setUptime(new Date());
	    	            if (!ids.isEmpty()){
	    	            	tv.setBz("MES-" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()) + " fid:" + ids);
	    	            }
	    	            tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tv);
	    			}else{
	    				tv = new TRmWorkprocProductValue();
	    				tv.setItemid(itemid);
	    				tv.setClock(clock);
	    				tv.setTimegranid(timegranid);
	    				tv.setItemtype(itemid.substring(itemid.length()-1, itemid.length()));
	    	            //计算值
	    				tv.setActualvalue(new BigDecimal(actualvalue).setScale(digits, RoundingMode.HALF_UP));
	    	            //修正值
	    				tv.setCorrectvalue(new BigDecimal(0));
	    	            //最终值
	    				tv.setApportvalue(new BigDecimal(actualvalue).setScale(digits, RoundingMode.HALF_UP));
	    				tv.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
	    				if (!ids.isEmpty()){
	    	            	tv.setBz("MES-" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()) + " fid:" + ids);
	    	            }
	    	            tRmWorkprocProductValueMapper.insert(tv);
	    			}
				}else{
					HashMap<String, Object> id = new HashMap<String, Object>();
		    		id.put("clock", clock);
		    		id.put("timegranid", timegranid);
		    		id.put("itemid", itemid);
		    		id.put("itemtype", itemid.substring(itemid.length()-1, itemid.length()));
		    		HashMap<String, Object> maps = new HashMap<>();
		        	if(timegranid.equalsIgnoreCase("MONTH")){
			            maps.put("itemid", itemid);
			            maps.put("clock", clock);
			            maps.put("timegranid", "DAY");
		        	}else if(timegranid.equalsIgnoreCase("YEAR")){
		        		maps.put("itemid", itemid);
			            maps.put("clock", clock);
			            maps.put("timegranid", "MONTH");
		        	}
		        	// 计算值
		        	BigDecimal actualvalue = new BigDecimal(tRmWorkprocProductValueMapper.getSumvalue(maps)).setScale(digits, RoundingMode.HALF_UP);
		    		// 数据是否已存在
		    		TRmWorkprocProductValue tv = tRmWorkprocProductValueMapper.selectByPrimaryKey(id);
					if(tv!=null){
						tv.setActualvalue(actualvalue);
			            tv.setApportvalue(BigDecimalUtil.add(tv.getCorrectvalue()!=null?tv.getCorrectvalue().doubleValue():0d, actualvalue.doubleValue()));
			            tv.setUptime(new Date());
			            tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tv);
					}else{
						TRmWorkprocProductValue trm = new TRmWorkprocProductValue();
						trm.setItemid(itemid);
		    			trm.setClock(clock);
		    			trm.setTimegranid(timegranid);
		    			trm.setItemtype(itemid.substring(itemid.length()-1, itemid.length()));
			            //计算值
		    			trm.setActualvalue(actualvalue);
			            //修正值
		    			trm.setCorrectvalue(new BigDecimal(0));
			            //最终值
		    			trm.setApportvalue(actualvalue);
			            trm.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
			            tRmWorkprocProductValueMapper.insert(trm);
					}
				}
			}
		} catch (Exception e) {
			logger.error("统计错误：itemid-" + itemid + ",clock-" + clock);
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void restatAllRData1(String clock, String timegranid) {
		// 先获取所有的公式类型项目
        List<TRmWorkprocProduct> IdAndDigits = tRmWorkprocProductService.getIdAndDigits("");
        for (TRmWorkprocProduct IdAndDigit : IdAndDigits) {
        	if(timegranid.equalsIgnoreCase("DAY")){
        		//获取公式内容
                String formula = formulaService.getFormula(IdAndDigit.getItemid(), clock);
                //获取计算值
                Double  actualvalue= formulaService.getValByFormula(formula, "DAY", clock, IdAndDigit.getDigits(), 0);
                if(actualvalue<0){
                    actualvalue=0.0;
                    logger.info("id为"+IdAndDigit.getItemid()+"计算错误");
                }
                // 删除需要更新的数据项
				HashMap<String, Object> id = new HashMap<String, Object>();
				id.put("clock", clock);
				id.put("itemid", IdAndDigit.getItemid());
				id.put("timegranid", "DAY");
				id.put("itemtype", "R");
				TRmWorkprocProductValue trm = tRmWorkprocProductValueMapper.selectByPrimaryKey(id);
				if(trm!=null){
					trm.setActualvalue(new BigDecimal(actualvalue));
					trm.setApportvalue(BigDecimalUtil.add(trm.getCorrectvalue()!=null?trm.getCorrectvalue().doubleValue():0d, actualvalue));
					trm.setUptime(new Date());
		            tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(trm);
				}else{
					TRmWorkprocProductValue tRmWorkprocProductValue = new TRmWorkprocProductValue();
	                //最终值
	                tRmWorkprocProductValue.setApportvalue(new BigDecimal(actualvalue));
	                //时间
	                tRmWorkprocProductValue.setClock(clock);
	                //类型
	                tRmWorkprocProductValue.setItemtype(IdAndDigit.getItemtype());
	                //时间粒度
	                tRmWorkprocProductValue.setTimegranid("DAY");
	                //获取关联d
	                tRmWorkprocProductValue.setItemid(IdAndDigit.getItemid());
	                //计算值
	                tRmWorkprocProductValue.setActualvalue(new BigDecimal(actualvalue));
	                tRmWorkprocProductValue.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
	                this.insert(tRmWorkprocProductValue);
				}
        	}else{
        		HashMap<String, Object> id = new HashMap<String, Object>();
        		id.put("clock", clock);
        		id.put("timegranid", timegranid);
        		id.put("itemid", IdAndDigit.getItemid());
        		id.put("itemtype", "R");
        		HashMap<String, Object> maps = new HashMap<>();
            	if(timegranid.equalsIgnoreCase("MONTH")){
    	            maps.put("itemid", IdAndDigit.getItemid());
    	            maps.put("clock", clock);
    	            maps.put("timegranid", "DAY");
            	}else if(timegranid.equalsIgnoreCase("YEAR")){
            		maps.put("itemid", IdAndDigit.getItemid());
    	            maps.put("clock", clock);
    	            maps.put("timegranid", "MONTH");
            	}
            	// 计算值
                Double actualvalue = tRmWorkprocProductValueMapper.getSumvalue(maps);
				// 数据是否已存在
				TRmWorkprocProductValue tv = tRmWorkprocProductValueMapper.selectByPrimaryKey(id);
				if (tv != null) {
					tv.setActualvalue(new BigDecimal(actualvalue));
					tv.setApportvalue(BigDecimalUtil
							.add(tv.getCorrectvalue() != null ? tv.getCorrectvalue().doubleValue() : 0d, actualvalue));
					tv.setUptime(new Date());
					tRmWorkprocProductValueMapper.updateByPrimaryKeySelective(tv);
				} else {
					TRmWorkprocProductValue trm = new TRmWorkprocProductValue();
					trm.setItemid(IdAndDigit.getItemid());
					trm.setClock(clock);
					trm.setTimegranid(timegranid);
					trm.setItemtype("R");
					// 计算值
					trm.setActualvalue(new BigDecimal(actualvalue));
					// 修正值
					trm.setCorrectvalue(new BigDecimal(0));
					// 最终值
					trm.setApportvalue(new BigDecimal(actualvalue));
					trm.setUpdatetime(DateUtils.dateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
					tRmWorkprocProductValueMapper.insert(trm);
				}
        	}
        }
	}

	@Override
	public Double getProductvalue(HashMap<String, Object> params) {
		if (params == null) {
			return null;
		}
		if (params.get("workprocid")==null || params.get("clock")==null || params.get("timegranid")==null) {
			return null;
		}
		return tRmWorkprocProductValueMapper.getProductvalue(params);
	}
}
