/***文档注释***********************************************
 * 作者            ：bin.pan
 * 创建日期     ：2018-09-19
 * 描述            ：工序设计信息
 * 注意事项     ：同一工序可能出现多次,分清楚是第几次
 * 遗留BUG   ：
 * 修改日期     ：
 * 修改人员     ：
 * 修改内容     ：
***********************************************************/
package market.Api.Mes.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import market.Api.Lms.impl.LmsApiServiceImpl;
import market.Api.Mes.service.MesApiDesignInfoService;
import market.Api.Qms.impl.QmsApiServiceImpl;
import market.Com.mapper.ComBaseInfoMapper;
import market.Com.mapper.ComBaseProcessRStationMapper;
import market.Com.mapper.ComDsnPltlmtMapper;
import market.Com.mapper.PbModelDbMapper;
import market.Com.pb.DoubleUtil;
import market.Com.vo.ComBaseInfo;
import market.Com.vo.ComBaseProcessRStation;
import market.Com.vo.ComDsnPltlmt;
import market.Com.vo.CommonPage;
import market.Com.vo.PbModelDb;
import market.Com.vo.ResultModel;
import market.Lms.Warehouse.mapper.YdmProductDetailMapper;
import market.Lms.Warehouse.mapper.YdmProductInlistMapper;
import market.Lms.Warehouse.vo.YdmProductDetail;
import market.Lms.Warehouse.vo.YdmProductInlist;
import market.Mes.Cuttolength.Design.mapper.PlnCuttolengthDsnMainMapper;
import market.Mes.Cuttolength.Design.mapper.PlnCuttolengthDsnMultinfoMapper;
import market.Mes.Cuttolength.Design.vo.ClRestrict;
import market.Mes.Cuttolength.Design.vo.PlnCuttolengthDsnMain;
import market.Mes.Cuttolength.Design.vo.PlnCuttolengthDsnMultinfo;
import market.Mes.Cuttolength.Plan.impl.PlnCuttolengthPlanServiceImpl;
import market.Mes.Cuttolength.Plan.mapper.PlnCuttolengthPlanDetailMapper;
import market.Mes.Cuttolength.Plan.vo.PlnCuttolengthPlanDetail;
import market.Mes.Lengthwise.Design.mapper.PlnDsnOrderInfoMapper;
import market.Mes.Lengthwise.Design.mapper.PlnLengthwiseDsnMainMapper;
import market.Mes.Lengthwise.Design.mapper.PlnLengthwiseDsnMultinfoMapper;
import market.Mes.Lengthwise.Design.vo.PlnDsnOrderInfo;
import market.Mes.Lengthwise.Design.vo.PlnLengthwiseDsnMain;
import market.Mes.Lengthwise.Design.vo.PlnLengthwiseDsnMultinfo;
import market.Mes.Lengthwise.Plan.impl.PlnLengthwisePlanServiceImpl;
import market.Mes.Lengthwise.Plan.mapper.PlnLengthwisePlanDetailMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnMatReplaceLogMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnMaterielDetailMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnProcessPlanMapper;
import market.Mes.Lengthwise.Plan.vo.PlnLengthwisePlanDetail;
import market.Mes.Lengthwise.Plan.vo.PlnMatReplaceLog;
import market.Mes.Lengthwise.Plan.vo.PlnMaterielDetail;
import market.Mes.Lengthwise.Plan.vo.PlnProcessPlan;
import market.Mes.MaterielTrack.mapper.PrcMaterielExtinfoMapper;
import market.Mes.MaterielTrack.mapper.PrcMaterielProcessMapper;
import market.Mes.MaterielTrack.vo.PrcMaterielExtinfo;
import market.Mes.Opr.mapper.MesOprLogMapper;
import market.Mes.Opr.vo.MesOprLog;
import market.Mes.OrderManager.Plan.mapper.PlnOrderStatisticMapper;
import market.Mes.OrderManager.Plan.mapper.PlnProdorderExtinfoMapper;
import market.Mes.OrderManager.Plan.mapper.PlnProdorderMapper;
import market.Mes.OrderManager.Plan.mapper.PlnProdorderStatisticMapper;
import market.Mes.OrderManager.Plan.vo.PlnOrderStatistic;
import market.Mes.OrderManager.Plan.vo.PlnProdorder;
import market.Mes.OrderManager.Plan.vo.PlnProdorderStatistic;
import market.Mes.Pickle.Design.impl.PlnPickleDsnMultinfoServiceImpl;
import market.Mes.Pickle.Design.mapper.PlnPickleDsnMainMapper;
import market.Mes.Pickle.Design.mapper.PlnPickleDsnMultinfoMapper;
import market.Mes.Pickle.Design.vo.PlnPickleDsnMain;
import market.Mes.Pickle.Design.vo.PlnPickleDsnMultinfo;
import market.Mes.Pickle.Plan.mapper.PlnPicklePlanDetailMapper;
import market.Mes.Pickle.Plan.vo.PlnPicklePlanDetail;
import market.Mes.Rolling.Design.impl.PlnRollingDsnMultinfoServiceImpl;
import market.Mes.Rolling.Design.mapper.PlnRollingDsnMainMapper;
import market.Mes.Rolling.Design.mapper.PlnRollingDsnMultinfoMapper;
import market.Mes.Rolling.Design.vo.PlnRollingDsnMain;
import market.Mes.Rolling.Design.vo.PlnRollingDsnMultinfo;
import market.Mes.Rolling.Plan.mapper.PlnRollingPlanDetailMapper;
import market.Mes.Rolling.Plan.vo.PlnRollingPlanDetail;
import market.Mes.Tpm.Design.impl.PlnSkinrollingDsnMultinfoServiceImpl;
import market.Mes.Tpm.Design.mapper.PlnSkinrollingDsnMainMapper;
import market.Mes.Tpm.Design.mapper.PlnSkinrollingDsnMultinfoMapper;
import market.Mes.Tpm.Design.vo.PlnSkinrollingDsnMain;
import market.Mes.Tpm.Design.vo.PlnSkinrollingDsnMultinfo;
import market.Mes.Tpm.mapper.PlnSkinrollingPlanDetailMapper;
import market.Mes.Tpm.vo.PlnSkinrollingPlanDetail;
import market.Mes.anneal.Design.impl.PlnAnnealDsnMultinfoServiceImpl;
import market.Mes.anneal.Design.mapper.PlnAnnealDsnMainMapper;
import market.Mes.anneal.Design.mapper.PlnAnnealDsnMultinfoMapper;
import market.Mes.anneal.Design.vo.PlnAnnealDsnMain;
import market.Mes.anneal.Design.vo.PlnAnnealDsnMultinfo;
import market.Mes.anneal.mapper.PlnAnnealPlanDetailMapper;
import market.Mes.anneal.vo.PlnAnnealPlanDetail;
import market.Qms.slmord.mapper.SlmOrdDesignMscPlGxPrlMapper;
import market.Qms.slmord.mapper.SlmOrdDesignMscPlMapper;
import market.Qms.slmord.mapper.SlmOrdDesignMscPlStiMapper;
import market.Qms.slmord.vo.SlmOrdDesignMscPl;
import market.Qms.slmord.vo.SlmOrdDesignMscPlGxPrl;
import market.Qms.slmord.vo.SlmOrdDesignMscPlSti;
import market.Qms.slmord.vo.SlmOrdDesignMscTic;
import market.Qms.slmord.vo.SlmOrdDesignMscTicItem;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import com.hnshituo.basic.service.impl.BaseServiceImpl;
import com.hnshituo.basic.spring.remoting.annotation.RemoteService;
import com.hnshituo.core.auth.service.HomeService;

@RemoteService(path = "MesApiDesignInfoService")
public class MesApiDesignInfoImpl extends BaseServiceImpl implements MesApiDesignInfoService {

	/**
	 * 生成设计信息
	 * 
	 * @param prod_order_no    生产订单号
	 * @param process          订单对应的工序点集合
	 * @param currentprocindex 对象指针
	 * @param object_no_vt     虚拟母卷号(不存在则生成)
	 * @param single_wgt       单重
	 * @return
	 * 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel Design_Plan_Info(List<DesignInfo> infos, Map<String, Integer> proc_times) throws Exception {
		ResultModel rm = new ResultModel("200", "");
		if (proc_times == null) {
			proc_times = new HashMap<String, Integer>();
		}
		List<DesignInfo> result = new ArrayList<>();
		String prev_process_code = "", next_process_code = "";
		if (Utils.isEmpty(infos)) {
			rm.setState("500");
			rm.setMsgInfo("请传入数据!");
			return rm;
		}
		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);

		for (DesignInfo info : infos) {
			if (Utils.isEmpty(info.getProcess())) {
				rm.setState("500");
				rm.setMsgInfo("传入工艺路径为空!");
				return rm;
			}
			List<DesignInfo> infons = new ArrayList<DesignInfo>();
			if (info.getCurrentProcIndex() >= info.getProcess().size()) {
				continue;
			}
			// 工序点
			String cur_proc = info.getProcess().get(info.getCurrentProcIndex());
			// 复制母卷的设计次数
			Map<String, Integer> temp = new HashMap<String, Integer>();
			temp.putAll(proc_times);
			if (temp.containsKey(cur_proc)) {
				temp.put(cur_proc, temp.get(cur_proc) + 1);
			} else {
				temp.put(cur_proc, 1);
			}

			// 罩退
			if (cur_proc.equals(processpoint.anneal_code)) {
				// 获取当前工序的上下工序
				if (info.getCurrentProcIndex() > 0) {
					prev_process_code = info.getProcess().get(info.getCurrentProcIndex() - 1);
				}
				if (info.getCurrentProcIndex() < info.getProcess().size() - 1) {
					next_process_code = info.getProcess().get(info.getCurrentProcIndex() + 1);
				}
				// 生成设计信息
				result = AnnealPlanDsn(info.getProd_order_no(), info.getObject_no_vt(), prev_process_code,
						next_process_code, info.getSingle_wgt(), info.getObject_no(),
						temp.get(processpoint.anneal_code));
				// 引用指针加一
				info.setCurrentProcIndex(info.getCurrentProcIndex() + 1);
				// 生成当前工序子卷参数
				infons = GetChildParam(result, info);
				// 分条
			} else if (cur_proc.equals(processpoint.slitting_code)) {
				// 获取当前工序的上下工序
				if (info.getCurrentProcIndex() > 0) {
					prev_process_code = info.getProcess().get(info.getCurrentProcIndex() - 1);
				}
				if (info.getCurrentProcIndex() < info.getProcess().size() - 1) {
					next_process_code = info.getProcess().get(info.getCurrentProcIndex() + 1);
				}
				// 生成设计信息
				result = LengthwisePlanDsn(info.getProd_order_no(), info.getObject_no_vt(), prev_process_code,
						next_process_code, info.getSingle_wgt(), info.getObject_no(),
						temp.get(processpoint.slitting_code));
				// 引用指针加一
				info.setCurrentProcIndex(info.getCurrentProcIndex() + 1);
				// 生成当前工序子卷参数
				infons = GetChildParam(result, info);
				// 开平
			} else if (cur_proc.equals(processpoint.cross_cutting_code)) {
				// 获取当前工序的上下工序
				if (info.getCurrentProcIndex() > 0) {
					prev_process_code = info.getProcess().get(info.getCurrentProcIndex() - 1);
				}
				if (info.getCurrentProcIndex() < info.getProcess().size() - 1) {
					next_process_code = info.getProcess().get(info.getCurrentProcIndex() + 1);
				}
				// 生成设计信息
				result = CuttolengthPlanDsn(info.getProd_order_no(), info.getObject_no_vt(), prev_process_code,
						next_process_code, info.getSingle_wgt(), info.getObject_no(),
						temp.get(processpoint.cross_cutting_code));
				// 引用指针加一
				info.setCurrentProcIndex(info.getCurrentProcIndex() + 1);
				// 生成当前工序子卷参数
				infons = GetChildParam(result, info);
				// 平整
			} else if (cur_proc.equals(processpoint.smooth_code)) {
				// 获取当前工序的上下工序
				if (info.getCurrentProcIndex() > 0) {
					prev_process_code = info.getProcess().get(info.getCurrentProcIndex() - 1);
				}
				if (info.getCurrentProcIndex() < info.getProcess().size() - 1) {
					next_process_code = info.getProcess().get(info.getCurrentProcIndex() + 1);
				}
				// 生成设计信息
				result = SrPlanDsn(info.getProd_order_no(), info.getObject_no_vt(), prev_process_code,
						next_process_code, info.getSingle_wgt(), info.getObject_no(),
						temp.get(processpoint.smooth_code));
				// 引用指针加一
				info.setCurrentProcIndex(info.getCurrentProcIndex() + 1);
				// 生成当前工序子卷参数
				infons = GetChildParam(result, info);
				// 轧制
			} else if (cur_proc.equals(processpoint.rolling_code)) {
				// 获取当前工序的上下工序
				if (info.getCurrentProcIndex() > 0) {
					prev_process_code = info.getProcess().get(info.getCurrentProcIndex() - 1);
				}
				if (info.getCurrentProcIndex() < info.getProcess().size() - 1) {
					next_process_code = info.getProcess().get(info.getCurrentProcIndex() + 1);
				}
				// 生成设计信息
				result = RollingPlanDsn(info.getProd_order_no(), info.getObject_no_vt(), prev_process_code,
						next_process_code, info.getSingle_wgt(), info.getObject_no(),
						temp.get(processpoint.rolling_code));
				// 引用指针加一
				info.setCurrentProcIndex(info.getCurrentProcIndex() + 1);
				// 生成当前工序子卷参数
				infons = GetChildParam(result, info);
				// 酸洗
			} else if (cur_proc.equals(processpoint.pickle_code)) {
				// 获取当前工序的上下工序
				if (info.getCurrentProcIndex() > 0) {
					prev_process_code = info.getProcess().get(info.getCurrentProcIndex() - 1);
				}
				if (info.getCurrentProcIndex() < info.getProcess().size() - 1) {
					next_process_code = info.getProcess().get(info.getCurrentProcIndex() + 1);
				}
				// 生成设计信息
				result = PicklePlanDsn(info.getProd_order_no(), info.getObject_no_vt(), prev_process_code,
						next_process_code, info.getSingle_wgt(), info.getObject_no(),
						temp.get(processpoint.pickle_code));
				// 引用指针加一
				info.setCurrentProcIndex(info.getCurrentProcIndex() + 1);
				// 生成当前工序子卷参数
				infons = GetChildParam(result, info);
			}
			if (Utils.isEmpty(infons)) {
				continue;
			}
			if (info.getCurrentProcIndex() < info.getProcess().size()) {
				rm = Design_Plan_Info(infons, temp);
				if (!"200".equals(rm.getState())) {
					throw new Exception(rm.getMsgInfo());
				}
			}
		}
		return rm;
	}

	/**
	 * 轧制设计信息
	 * 
	 * @param prod_order_no     生产订单号
	 * @param object_no_vt      虚拟母卷号
	 * @param prev_process_code 上道工序
	 * @param next_process_code 下道工序
	 * @param proc_times        生成主表设计信息、拼料信息、虚拟物料信息、订单组成信息
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public List<DesignInfo> RollingPlanDsn(String prod_order_no, String object_no_vt, String prev_process_code,
			String next_process_code, Double single_wgt, String object_no, Integer proc_times) throws Exception {

		List<DesignInfo> result = new ArrayList<>();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
//		double othickmin = 0, othickmax = 0, thick = 0;
		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
//		Double width = 0d;

		boolean obv_flg = false;
		// 获取虚拟母卷信息
		List<PlnMaterielDetail> pmdel = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			pmdel = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		if (Utils.isNotEmpty(pmdel) && pmdel.get(0).getRl_design_no() != null) {
			obv_flg = true;
		}
		// 获取订单信息
		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(prod_order_no);
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);
		// 获取成品厚度信息
		// 获取轧制工序信息
		// 获取质量设计信息取轧制工序最后一个道次信息
//		SlmOrdDesignMscPlSti sti = new SlmOrdDesignMscPlSti();
//		sti.setDesign_key(lpp.get(0).getDesign_key());
//		sti.setMsc_pline(lpp.get(0).getMsc_pline());
//		sti.setProcess_code(processpoint.rolling_code);
//		List<SlmOrdDesignMscPlSti> stis = this.getBean(MesApiDesignInfoImpl.class).getQcmPrcInfo(sti);
//		// 获取当前工序的最后一个道次信息
//		sti.setBacklog_seq(stis.get(proc_times - 1).getBacklog_seq());
//		// 只查询工艺类工序点
//		sti.setProcess_point_type("403206");
//		List<SlmOrdDesignMscPlSti> listSti = this.getMapper(SlmOrdDesignMscPlStiMapper.class).findWithCondition(sti, "",
//				" PROCESS_POINT_SEQ desc", 0, 0);
//		SlmOrdDesignMscPlSti smp = listSti.get(0);
//		SlmOrdDesignMscTic tmp = new SlmOrdDesignMscTic();
//		BeanUtils.copyProperties(smp, tmp);
//		tmp.setPline_code("C016");
//		tmp.setMachine_code("M0008");
//		CommonPage<SlmOrdDesignMscTic> com = new CommonPage<SlmOrdDesignMscTic>();
//		com.setObject(tmp);
//		ResultModel tic_f = this.getBean(QmsApiServiceImpl.class).getGongYi(com);
//		if ("500".equals(tic_f.getState())) {
//			throw new Exception("获取[" + tmp.getProcess_point_desc() + "]工艺标准失败!" + tic_f.getMsgInfo());
//		}
//		if (Utils.isNotEmpty(tic_f)) {
//			List<SlmOrdDesignMscTicItem> item_f = (List<SlmOrdDesignMscTicItem>) tic_f.getData();
//			// 获取轧制入口厚度出口厚度的代码
////		SlmOrdDesignMscTicItem tmp = new SlmOrdDesignMscTicItem();
//			List<PbModelDb> code = this.getBean(MesApiDesignInfoImpl.class).getBase_Name("201001");
//			for (SlmOrdDesignMscTicItem slm : item_f) {
//				// 出口厚度
//				if (slm.getCraft_param_code().equals(code.get(1).getText())) {
//					othickmin = Double.valueOf(slm.getMin_value() == null ? "0" : slm.getMin_value());
//					if (Utils.isNotEmpty(slm.getMax_value())) {
//						othickmax = Double.valueOf(slm.getMax_value());
//					}
//					break;
//				}
//				// 入口厚度
//// 
//			}
//			thick = othickmin == 0 ? othickmax : othickmin;
//			if (Utils.isNotEmpty(pmdel)) {
//				width = pmdel.get(0).getWidth();
//			} else {
//				width = lpp.get(0).getWidth();
//			}
//		}
		// 计算所需原料卷数量
//		int db_cnt = (new BigDecimal(lpp.get(0).getEstimate_weight()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue() == 0 ? 1:(new BigDecimal(lpp.get(0).getEstimate_weight()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue();
		String sDate = new SimpleDateFormat("yyMMdd").format(new Date());
		PlnRollingDsnMain pldm = new PlnRollingDsnMain();

		// 设计信息存在就修改设计主表
		if (obv_flg) {
			// 设计主表不变
			// 删除原有拼料信息'
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(lpp.get(0).getWidth());
			pldm.setLength(lpp.get(0).getLength());
			pldm.setRl_design_no(pmdel.get(0).getRl_design_no());
			this.getMapper(PlnRollingDsnMultinfoMapper.class).doDelete(pmdel.get(0).getRl_design_no());
		} else {
			// 保存设计主表数据： 轧制设计号：DRL+YYMMDD+6流水号
			List<PlnRollingDsnMain> lpdmNo = this.getMapper(PlnRollingDsnMainMapper.class).findWithCondition(null, "",
					" serial_no desc ", 0, 1);
			pldm.setSerial_no(1l);
			pldm.setRl_design_no("DRL" + sDate + String.format("%06d", 1));
			if (lpdmNo != null && lpdmNo.size() > 0) {
				pldm.setSerial_no(lpdmNo.get(0).getSerial_no() + 1);
				if (sDate.equals(lpdmNo.get(0).getRl_design_no().substring(3, 9))) {
					pldm.setRl_design_no("DRL" + sDate + String.format("%06d",
							Integer.parseInt(lpdmNo.get(0).getRl_design_no().substring(9, 15)) + 1));
				}
			}

			// 订单信息
			pldm.setProd_order_no(lpp.get(0).getProd_order_no());
			pldm.setOrder_no(lpp.get(0).getOrder_no());
			pldm.setPline_code(lpp.get(0).getPline_code());
			pldm.setSteel_code(lpp.get(0).getSteel_code());
			String isMulti = "0";// 是否拼料 根据订单数判断，多个订单填1，否则填0
			pldm.setIs_multi(isMulti);
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(lpp.get(0).getWidth());
			pldm.setLength(lpp.get(0).getLength());
			pldm.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pldm.setDiameter_out(lpp.get(0).getDiameter_out());
			pldm.setSingle_weight(single_wgt);
//		pldm.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//		pldm.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pldm.setDeliver_date(lpp.get(0).getDeliver_date());
			pldm.setDesign_quantity(1);
			pldm.setDesign_weight(single_wgt); // 实物单重
			pldm.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pldm.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pldm.setSub_count(1L);
			pldm.setCreate_man_name(userName);
			pldm.setCreate_time(new Date());
			pldm.setIs_finished(0L);
			pldm.setReserve_1(lpp.get(0).getProduce_no());
			this.getMapper(PlnRollingDsnMainMapper.class).insert(pldm);
		}

		// 倒叙取一条拼料信息
		List<PlnRollingDsnMultinfo> lpdmM = this.getMapper(PlnRollingDsnMultinfoMapper.class).findWithCondition(null,
				"", " serial_no desc ", 0, 1);
		long DsnNo = 1;
		if (lpdmM != null && lpdmM.size() > 0) {
			DsnNo = lpdmM.get(0).getSerial_no() + 1;
		}

		// -----------------写拼料信息-----------------------------
		PlnRollingDsnMultinfo pldmc = new PlnRollingDsnMultinfo();
		pldmc.setSerial_no(DsnNo);
		pldmc.setRl_design_no(pldm.getRl_design_no());
		pldmc.setSeg_seq(1);
		pldmc.setOrder_no(lpp.get(0).getOrder_no());
		pldmc.setProd_order_no(lpp.get(0).getProd_order_no());
		pldmc.setThick(lpp.get(0).getThick());
		pldmc.setWidth(lpp.get(0).getWidth());
		pldmc.setLength(lpp.get(0).getLength());
		pldmc.setDiameter_inn(lpp.get(0).getDiameter_inn());
		pldmc.setDiameter_out(lpp.get(0).getDiameter_out());
		pldmc.setWeight(single_wgt);
//		pldmc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//		pldmc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
		pldmc.setSub_seq(1);
		this.getMapper(PlnRollingDsnMultinfoMapper.class).insert(pldmc);

		// 生成虚拟物料信息倒叙去一条
		List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long PMDNo = 1;
		if (lpmd != null && lpmd.size() > 0) {
			PMDNo = lpmd.get(0).getSerial_no() + 1;
		}
		int objectnoVtNo = this.getMapper(PlnMaterielDetailMapper.class).getObjectVtMaxNoForDate(sDate) + 1;

		List<PlnMaterielDetail> detail = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			detail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}
		
		YdmProductDetail ypd = new YdmProductDetail();
		if (Utils.isNotEmpty(object_no)) {
			// 获取实物库存信息
			ypd = this.getMapper(YdmProductDetailMapper.class).findById(object_no);
		}

		// 虚拟母卷计划内的才需要新增或者修改
		PlnMaterielDetail pmdM = new PlnMaterielDetail();
		if (Utils.isNotEmpty(detail)) {
			pmdM = detail.get(0);
			pmdM.setStatus("0PDE10");
			if (Utils.isNotEmpty(object_no)) {
				pmdM.setObject_no(object_no);
				if(Utils.isNotEmpty(ypd)) {
					pmdM.setThick(ypd.getThick());
				}
			}
			pmdM.setNext_dsn_process_code(processpoint.rolling_code);
			pmdM.setNext_process_code(processpoint.rolling_code);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setRl_design_no(pldm.getRl_design_no());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			// 存在大批量脱单的时候，卷子虚拟物料信息的卷号信息没被清空，所以再次挂单的时候，选择直接更新订单号：
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnMaterielDetailMapper.class).update(pmdM);
		} else {
			pmdM.setSerial_no(PMDNo++);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setObject_no_vt(object_no_vt == null ? sDate + String.format("%06d", objectnoVtNo++) : object_no_vt);
			pmdM.setObject_no(object_no);
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setPline_code(lpp.get(0).getPline_code());
			pmdM.setStatus("0PDE10");
			pmdM.setIs_finished("0");
//			pmdM.setPrev_dsn_process_code(prev_process_code);
//			pmdM.setPrev_process_code(prev_process_code);
			pmdM.setNext_dsn_process_code(processpoint.rolling_code);
			pmdM.setNext_process_code(processpoint.rolling_code);
			pmdM.setIs_prev_dsn_finished("0");// 母卷：0
			pmdM.setCreate_design_no(pldm.getRl_design_no());
			pmdM.setCreate_process_code(processpoint.rolling_code);
			pmdM.setIs_mat(1);// 母卷：1
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setRl_design_no(pldm.getRl_design_no());
			pmdM.setIs_multi("0");
			pmdM.setSteel_code(lpp.get(0).getSteel_code());
			// 母卷厚度、宽度使用实物规格
			if (Utils.isNotEmpty(object_no)) {
				if(Utils.isNotEmpty(ypd)) {
					pmdM.setThick(ypd.getThick());
					pmdM.setWidth(ypd.getWidth());
					pmdM.setLength(ypd.getLength());
				}else {
					pmdM.setWidth(lpp.get(0).getWidth());
					pmdM.setThick(lpp.get(0).getThick());
					pmdM.setLength(lpp.get(0).getLength());
				}
			}else {
				pmdM.setWidth(lpp.get(0).getWidth());
				pmdM.setThick(lpp.get(0).getThick());
				pmdM.setLength(lpp.get(0).getLength());
			}
			pmdM.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pmdM.setDiameter_out(lpp.get(0).getDiameter_out());
			pmdM.setSingle_weight(single_wgt);
			pmdM.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdM.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdM.setOrd_flg("1");
			pmdM.setCreate_man_name(userName);
			pmdM.setCreate_time(new Date());
			pmdM.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdM.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdM);
		}

		// 根据累加值，建立坯料设计订单组成表
		long pdoiNo = 1;
		List<PlnDsnOrderInfo> lpdoiq = this.getMapper(PlnDsnOrderInfoMapper.class).findWithCondition(null, "",
				" serial_no desc", 0, 1);
		if (lpdoiq != null && lpdoiq.size() > 0) {
			pdoiNo = lpdoiq.get(0).getSerial_no() + 1;
		}

		// 建立虚拟子卷信息
		PlnMaterielDetail pmdc = new PlnMaterielDetail();
		pmdc.setSerial_no(PMDNo++);
		pmdc.setObject_no_vt(sDate + String.format("%06d", objectnoVtNo++));
		pmdc.setOrder_no(lpp.get(0).getOrder_no());
		pmdc.setStatus("0PDE10");
		pmdc.setIs_finished("0");
		pmdc.setPrev_dsn_process_code(processpoint.rolling_code);
		pmdc.setPrev_process_code(processpoint.rolling_code);
		pmdc.setIs_prev_dsn_finished("1");// 母卷：0
		pmdc.setCreate_design_no(pldm.getRl_design_no());
		pmdc.setCreate_process_code(processpoint.rolling_code);
		pmdc.setIs_mat(0);// 母卷：1
		pmdc.setOrder_no(lpp.get(0).getOrder_no());
		pmdc.setProd_order_no(lpp.get(0).getProd_order_no());
		pmdc.setRl_design_no(pldm.getRl_design_no());
		pmdc.setMat_object_no_vt(pmdM.getObject_no_vt());
		pmdc.setIs_multi("0");
		pmdc.setSteel_code(lpp.get(0).getSteel_code());
		pmdc.setWidth(pldmc.getWidth());
		pmdc.setThick(pldmc.getThick());
		pmdc.setLength(pldmc.getLength());
		pmdc.setDiameter_inn(pldmc.getDiameter_inn());
		pmdc.setDiameter_out(pldmc.getDiameter_out());
		pmdc.setSub_count(1);
		// 母卷实重* 子卷计划宽度/母卷实宽
		pmdc.setSingle_weight(single_wgt);
		pmdc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
		pmdc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
		pmdc.setOrd_flg("1");
		pmdc.setCreate_man_name(userName);
		pmdc.setCreate_time(new Date());
		pmdc.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
		pmdc.setDeliver_date_latest(lpp.get(0).getDeliver_date());
		pmdc.setPk_ask_code(lpp.get(0).getPk_ask_code());
		pmdc.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
		this.getMapper(PlnMaterielDetailMapper.class).insert(pmdc);
		DesignInfo temp = new DesignInfo();
		temp.setObject_no_vt(pmdc.getObject_no_vt());
		temp.setSingle_wgt(pmdc.getSingle_weight());
		result.add(temp);

		// 订单组成信息
		PlnDsnOrderInfo pdoi = new PlnDsnOrderInfo();
		pdoi.setDesign_no(pldm.getRl_design_no());
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		pdoi.setWeight_in_one(single_wgt);
		pdoi.setQuantity_in_one(1);
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		if (obv_flg) {
			this.getMapper(PlnDsnOrderInfoMapper.class).doUpdate(pdoi);
		} else {
			pdoi.setSerial_no(pdoiNo++);
			pdoi.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnDsnOrderInfoMapper.class).insert(pdoi);
		}
		return result;
	}

	/**
	 * 平整设计信息
	 * 
	 * @param prod_order_no     生产订单号
	 * @param object_no_vt      虚拟母卷号
	 * @param prev_process_code 上道工序
	 * @param next_process_code 下道工序
	 * @param proc_times        生成主表设计信息、拼料信息、虚拟物料信息、订单组成信息
	 * @return
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public List<DesignInfo> SrPlanDsn(String prod_order_no, String object_no_vt, String prev_process_code,
			String next_process_code, Double single_wgt, String object_no, Integer proc_times) {
		List<DesignInfo> result = new ArrayList<>();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		Double width = 0d;
		boolean obv_flg = false;
		// 获取虚拟母卷信息
		List<PlnMaterielDetail> pmdel = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			pmdel = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		if (Utils.isNotEmpty(pmdel) && pmdel.get(0).getSr_design_no() != null) {
			obv_flg = true;
		}
		// 获取订单信息
		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(prod_order_no);
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);
		if (Utils.isNotEmpty(pmdel)) {
			width = pmdel.get(0).getWidth();
		} else {
			width = lpp.get(0).getWidth();
		}
		// 获取平整子卷重量
		ArrayList<Double> hts = howToSr(single_wgt, lpp.get(0).getEstimate_weight());
		String sDate = new SimpleDateFormat("yyMMdd").format(new Date());
		PlnSkinrollingDsnMain pldm = new PlnSkinrollingDsnMain();
		// 设计信息存在就修改设计主表
		if (obv_flg) {
			// 设计主表不变
			// 删除原有拼料信息
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(width);
			pldm.setLength(lpp.get(0).getLength());
			pldm.setSr_design_no(pmdel.get(0).getSr_design_no());
			this.getMapper(PlnSkinrollingDsnMultinfoMapper.class).doDelete(pmdel.get(0).getSr_design_no());
		} else {
			// 保存设计主表数据： 平整设计号：DSR+YYMMDD+6流水号
			List<PlnSkinrollingDsnMain> lpdmNo = this.getMapper(PlnSkinrollingDsnMainMapper.class)
					.findWithCondition(null, "", " serial_no desc ", 0, 1);
			pldm.setSerial_no(1l);
			pldm.setSr_design_no("DSR" + sDate + String.format("%06d", 1));
			if (lpdmNo != null && lpdmNo.size() > 0) {
				pldm.setSerial_no(lpdmNo.get(0).getSerial_no() + 1);
				if (sDate.equals(lpdmNo.get(0).getSr_design_no().substring(3, 9))) {
					pldm.setSr_design_no("DSR" + sDate + String.format("%06d",
							Integer.parseInt(lpdmNo.get(0).getSr_design_no().substring(9, 15)) + 1));
				}
			}

			// 订单信息
			pldm.setProd_order_no(lpp.get(0).getProd_order_no());
			pldm.setOrder_no(lpp.get(0).getOrder_no());
			pldm.setPline_code(lpp.get(0).getPline_code());
			pldm.setSteel_code(lpp.get(0).getSteel_code());
			String isMulti = "0";// 是否拼料 根据订单数判断，多个订单填1，否则填0
			pldm.setIs_multi(isMulti);
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(width);
			pldm.setLength(lpp.get(0).getLength());
			pldm.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pldm.setDiameter_out(lpp.get(0).getDiameter_out());
			pldm.setSingle_weight(single_wgt);
//				pldm.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//				pldm.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pldm.setDeliver_date(lpp.get(0).getDeliver_date());
			pldm.setDesign_quantity(1);
			pldm.setDesign_weight(single_wgt); // 实物单重
			pldm.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pldm.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pldm.setSub_count(hts.size());
			pldm.setCreate_man_name(userName);
			pldm.setCreate_time(new Date());
			pldm.setIs_finished(0L);
			pldm.setReserve_1(lpp.get(0).getProduce_no());
			this.getMapper(PlnSkinrollingDsnMainMapper.class).insert(pldm);
		}
		// 倒叙取一条拼料信息
		List<PlnSkinrollingDsnMultinfo> lpdmM = this.getMapper(PlnSkinrollingDsnMultinfoMapper.class)
				.findWithCondition(null, "", " serial_no desc ", 0, 1);
		long DsnNo = 1;
		if (lpdmM != null && lpdmM.size() > 0) {
			DsnNo = lpdmM.get(0).getSerial_no() + 1;
		}
		List<PlnSkinrollingDsnMultinfo> multinfo = new ArrayList<PlnSkinrollingDsnMultinfo>();
		for (int i = 0; i < hts.size(); i++) {
			// -----------------写拼料信息-----------------------------
			PlnSkinrollingDsnMultinfo pldmc = new PlnSkinrollingDsnMultinfo();
			pldmc.setSerial_no(DsnNo++);
			pldmc.setSr_design_no(pldm.getSr_design_no());
			pldmc.setSr_seq(Long.valueOf(i + 1));
			pldmc.setSeg_seq(Long.valueOf(i + 1));
			pldmc.setOrder_no(lpp.get(0).getOrder_no());
			pldmc.setProd_order_no(lpp.get(0).getProd_order_no());
			pldmc.setThick(lpp.get(0).getThick());
			pldmc.setWidth(width);
			pldmc.setLength(lpp.get(0).getLength() == null ? null
					: DoubleUtil.mul(DoubleUtil.div(hts.get(i), single_wgt), lpp.get(0).getLength()));
			pldmc.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pldmc.setDiameter_out(lpp.get(0).getDiameter_out());
			pldmc.setWeight(hts.get(i));
//				pldmc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//				pldmc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pldmc.setSub_seq(i + 1);
			this.getMapper(PlnSkinrollingDsnMultinfoMapper.class).insert(pldmc);
			multinfo.add(pldmc);
		}

		// 生成虚拟物料信息倒叙去一条
		List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long PMDNo = 1;
		if (lpmd != null && lpmd.size() > 0) {
			PMDNo = lpmd.get(0).getSerial_no() + 1;
		}
		int objectnoVtNo = this.getMapper(PlnMaterielDetailMapper.class).getObjectVtMaxNoForDate(sDate) + 1;

		List<PlnMaterielDetail> detail = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			detail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		// 虚拟母卷计划内的才需要新增或者修改
		PlnMaterielDetail pmdM = new PlnMaterielDetail();
		if (Utils.isNotEmpty(detail)) {
			pmdM = detail.get(0);
			pmdM.setStatus("0PDD10");
			if (Utils.isNotEmpty(object_no)) {
				pmdM.setObject_no(object_no);
			}
			pmdM.setNext_dsn_process_code(processpoint.smooth_code);
			pmdM.setNext_process_code(processpoint.smooth_code);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setSr_design_no(pldm.getSr_design_no());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			// 存在大批量脱单的时候，卷子虚拟物料信息的卷号信息没被清空，所以再次挂单的时候，选择直接更新订单号：
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnMaterielDetailMapper.class).update(pmdM);
		} else {
			pmdM.setSerial_no(PMDNo++);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setObject_no_vt(object_no_vt == null ? sDate + String.format("%06d", objectnoVtNo++) : object_no_vt);
			pmdM.setObject_no(object_no);
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setPline_code(lpp.get(0).getPline_code());
			pmdM.setStatus("0PDD10");
			pmdM.setIs_finished("0");
//					pmdM.setPrev_dsn_process_code(prev_process_code);
//					pmdM.setPrev_process_code(prev_process_code);
			pmdM.setNext_dsn_process_code(processpoint.smooth_code);
			pmdM.setNext_process_code(processpoint.smooth_code);
			pmdM.setIs_prev_dsn_finished("0");// 母卷：0
			pmdM.setCreate_design_no(pldm.getSr_design_no());
			pmdM.setCreate_process_code(processpoint.smooth_code);
			pmdM.setIs_mat(1);// 母卷：1
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setSr_design_no(pldm.getSr_design_no());
			pmdM.setIs_multi("0");
			pmdM.setSteel_code(lpp.get(0).getSteel_code());
			// 母卷厚度、宽度使用计划值
			pmdM.setWidth(width);
			pmdM.setThick(lpp.get(0).getThick());
			pmdM.setLength(lpp.get(0).getLength());
			pmdM.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pmdM.setDiameter_out(lpp.get(0).getDiameter_out());
			pmdM.setSingle_weight(single_wgt);
			pmdM.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdM.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdM.setOrd_flg("1");
			pmdM.setCreate_man_name(userName);
			pmdM.setCreate_time(new Date());
			pmdM.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdM.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdM);
		}

		// 根据累加值，建立坯料设计订单组成表
		long pdoiNo = 1;
		List<PlnDsnOrderInfo> lpdoiq = this.getMapper(PlnDsnOrderInfoMapper.class).findWithCondition(null, "",
				" serial_no desc", 0, 1);
		if (lpdoiq != null && lpdoiq.size() > 0) {
			pdoiNo = lpdoiq.get(0).getSerial_no() + 1;
		}
		for (PlnSkinrollingDsnMultinfo pm : multinfo) {
			// 建立虚拟子卷信息
			PlnMaterielDetail pmdc = new PlnMaterielDetail();
			pmdc.setSerial_no(PMDNo++);
			pmdc.setObject_no_vt(sDate + String.format("%06d", objectnoVtNo++));
			pmdc.setOrder_no(lpp.get(0).getOrder_no());
			pmdc.setStatus("0PDD10");
			pmdc.setIs_finished("0");
			pmdc.setPrev_dsn_process_code(processpoint.smooth_code);
			pmdc.setPrev_process_code(processpoint.smooth_code);
			pmdc.setIs_prev_dsn_finished("1");// 母卷：0
			pmdc.setCreate_design_no(pldm.getSr_design_no());
			pmdc.setCreate_process_code(processpoint.smooth_code);
			pmdc.setIs_mat(0);// 母卷：1
			pmdc.setOrder_no(lpp.get(0).getOrder_no());
			pmdc.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdc.setSr_design_no(pm.getSr_design_no());
			pmdc.setMat_object_no_vt(pmdM.getObject_no_vt());
			pmdc.setIs_multi("0");
			pmdc.setSteel_code(lpp.get(0).getSteel_code());
			pmdc.setWidth(pm.getWidth());
			pmdc.setThick(pm.getThick());
			pmdc.setLength(pm.getLength());
			pmdc.setDiameter_inn(pm.getDiameter_inn());
			pmdc.setDiameter_out(pm.getDiameter_out());

			// 母卷实重* 子卷计划宽度/母卷实宽
			pmdc.setSingle_weight(pm.getWeight());
			pmdc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdc.setOrd_flg("1");
			pmdc.setCreate_man_name(userName);
			pmdc.setCreate_time(new Date());
			pmdc.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdc.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdc.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdc.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdc);
			DesignInfo temp = new DesignInfo();
			temp.setObject_no_vt(pmdc.getObject_no_vt());
			temp.setSingle_wgt(pmdc.getSingle_weight());
			result.add(temp);
		}

		// 订单组成信息
		PlnDsnOrderInfo pdoi = new PlnDsnOrderInfo();
		pdoi.setDesign_no(pldm.getSr_design_no());
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		pdoi.setWeight_in_one(single_wgt);
		pdoi.setQuantity_in_one(hts.size());
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		if (obv_flg) {
			this.getMapper(PlnDsnOrderInfoMapper.class).doUpdate(pdoi);
		} else {
			pdoi.setSerial_no(pdoiNo++);
			pdoi.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnDsnOrderInfoMapper.class).insert(pdoi);
		}
		return result;
	}

	/**
	 * 罩退设计信息
	 * 
	 * @param prod_order_no     生产订单号
	 * @param object_no_vt      虚拟母卷号
	 * @param prev_process_code 上道工序
	 * @param next_process_code 下道工序
	 * @param proc_times        生成主表设计信息、拼料信息、虚拟物料信息、订单组成信息
	 * @return
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public List<DesignInfo> AnnealPlanDsn(String prod_order_no, String object_no_vt, String prev_process_code,
			String next_process_code, Double single_wgt, String object_no, Integer proc_times) {

		List<DesignInfo> result = new ArrayList<>();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		Double width = 0d;

		boolean obv_flg = false;
		// 获取虚拟母卷信息
		List<PlnMaterielDetail> pmdel = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			pmdel = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		if (Utils.isNotEmpty(pmdel) && pmdel.get(0).getAn_design_no() != null) {
			obv_flg = true;
		}
		// 获取订单信息
		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(prod_order_no);
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);
		if (Utils.isNotEmpty(pmdel)) {
			width = pmdel.get(0).getWidth();
		} else {
			width = lpp.get(0).getWidth();
		}
		// 计算所需原料卷数量
//		int db_cnt = (new BigDecimal(lpp.get(0).getEstimate_weight()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue() == 0 ? 1:(new BigDecimal(lpp.get(0).getEstimate_weight()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue();
		String sDate = new SimpleDateFormat("yyMMdd").format(new Date());
		PlnAnnealDsnMain pldm = new PlnAnnealDsnMain();

		// 设计信息存在就修改设计主表
		if (obv_flg) {
			// 设计主表不变
			// 删除原有拼料信息
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(width);
			pldm.setLength(lpp.get(0).getLength());
			pldm.setAn_design_no(pmdel.get(0).getAn_design_no());
			this.getMapper(PlnAnnealDsnMultinfoMapper.class).doDelete(pmdel.get(0).getAn_design_no());
		} else {
			// 保存设计主表数据： 罩退设计号：DAN+YYMMDD+6流水号
			List<PlnAnnealDsnMain> lpdmNo = this.getMapper(PlnAnnealDsnMainMapper.class).findWithCondition(null, "",
					" serial_no desc ", 0, 1);
			pldm.setSerial_no(1l);
			pldm.setAn_design_no("DAN" + sDate + String.format("%06d", 1));
			if (lpdmNo != null && lpdmNo.size() > 0) {
				pldm.setSerial_no(lpdmNo.get(0).getSerial_no() + 1);
				if (sDate.equals(lpdmNo.get(0).getAn_design_no().substring(3, 9))) {
					pldm.setAn_design_no("DAN" + sDate + String.format("%06d",
							Integer.parseInt(lpdmNo.get(0).getAn_design_no().substring(9, 15)) + 1));
				}
			}

			// 订单信息
			pldm.setProd_order_no(lpp.get(0).getProd_order_no());
			pldm.setOrder_no(lpp.get(0).getOrder_no());
			pldm.setPline_code(lpp.get(0).getPline_code());
			pldm.setSteel_code(lpp.get(0).getSteel_code());
			String isMulti = "0";// 是否拼料 根据订单数判断，多个订单填1，否则填0
			pldm.setIs_multi(isMulti);
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(width);
			pldm.setLength(lpp.get(0).getLength());
			pldm.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pldm.setDiameter_out(lpp.get(0).getDiameter_out());
			pldm.setSingle_weight(single_wgt);
//		pldm.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//		pldm.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pldm.setDeliver_date(lpp.get(0).getDeliver_date());
			pldm.setDesign_quantity(1);
			pldm.setDesign_weight(single_wgt); // 实物单重
			pldm.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pldm.setDeliver_date_latest(lpp.get(0).getDeliver_date());

			pldm.setCreate_man_name(userName);
			pldm.setCreate_time(new Date());
			pldm.setIs_finished(0L);
			pldm.setReserve_1(lpp.get(0).getProduce_no());
			this.getMapper(PlnAnnealDsnMainMapper.class).insert(pldm);
		}

		// 倒叙取一条拼料信息
		List<PlnAnnealDsnMultinfo> lpdmM = this.getMapper(PlnAnnealDsnMultinfoMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long DsnNo = 1;
		if (lpdmM != null && lpdmM.size() > 0) {
			DsnNo = lpdmM.get(0).getSerial_no() + 1;
		}

		// -----------------写拼料信息-----------------------------
		PlnAnnealDsnMultinfo pldmc = new PlnAnnealDsnMultinfo();
		pldmc.setSerial_no(DsnNo);
		pldmc.setAn_design_no(pldm.getAn_design_no());
//		pldmc.setAn_seq(1);
//		pldmc.setSeg_seq(1);
		pldmc.setOrder_no(lpp.get(0).getOrder_no());
		pldmc.setProd_order_no(lpp.get(0).getProd_order_no());
		pldmc.setThick(lpp.get(0).getThick());
		pldmc.setWidth(width);
		pldmc.setLength(lpp.get(0).getLength());
		pldmc.setDiameter_inn(lpp.get(0).getDiameter_inn());
		pldmc.setDiameter_out(lpp.get(0).getDiameter_out());
		pldmc.setWeight(single_wgt);
//		pldmc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//		pldmc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
		pldmc.setSub_seq(1);
		this.getMapper(PlnAnnealDsnMultinfoMapper.class).insert(pldmc);

		// 生成虚拟物料信息倒叙去一条
		List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long PMDNo = 1;
		if (lpmd != null && lpmd.size() > 0) {
			PMDNo = lpmd.get(0).getSerial_no() + 1;
		}
		int objectnoVtNo = this.getMapper(PlnMaterielDetailMapper.class).getObjectVtMaxNoForDate(sDate) + 1;

		List<PlnMaterielDetail> detail = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			detail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		// 虚拟母卷计划内的才需要新增或者修改
		PlnMaterielDetail pmdM = new PlnMaterielDetail();
		if (Utils.isNotEmpty(detail)) {
			pmdM = detail.get(0);
			pmdM.setStatus("0PDC10");
			if (Utils.isNotEmpty(object_no)) {
				pmdM.setObject_no(object_no);
			}
			pmdM.setNext_dsn_process_code(processpoint.anneal_code);
			pmdM.setNext_process_code(processpoint.anneal_code);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setAn_design_no(pldm.getAn_design_no());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			// 存在大批量脱单的时候，卷子虚拟物料信息的卷号信息没被清空，所以再次挂单的时候，选择直接更新订单号：
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnMaterielDetailMapper.class).update(pmdM);
		} else {
			pmdM.setSerial_no(PMDNo++);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setObject_no_vt(object_no_vt == null ? sDate + String.format("%06d", objectnoVtNo++) : object_no_vt);
			pmdM.setObject_no(object_no);
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setPline_code(lpp.get(0).getPline_code());
			pmdM.setStatus("0PDC10");
			pmdM.setIs_finished("0");
//			pmdM.setPrev_dsn_process_code(prev_process_code);
//			pmdM.setPrev_process_code(prev_process_code);
			pmdM.setNext_dsn_process_code(processpoint.anneal_code);
			pmdM.setNext_process_code(processpoint.anneal_code);
			pmdM.setIs_prev_dsn_finished("0");// 母卷：0
			pmdM.setCreate_design_no(pldm.getAn_design_no());
			pmdM.setCreate_process_code(processpoint.anneal_code);
			pmdM.setIs_mat(1);// 母卷：1
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setAn_design_no(pldm.getAn_design_no());
			pmdM.setIs_multi("0");
			pmdM.setSteel_code(lpp.get(0).getSteel_code());
			// 母卷厚度、宽度使用计划值
			pmdM.setWidth(width);
			pmdM.setThick(lpp.get(0).getThick());
			pmdM.setLength(lpp.get(0).getLength());
			pmdM.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pmdM.setDiameter_out(lpp.get(0).getDiameter_out());
			pmdM.setSingle_weight(single_wgt);
			pmdM.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdM.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdM.setOrd_flg("1");
			pmdM.setCreate_man_name(userName);
			pmdM.setCreate_time(new Date());
			pmdM.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdM.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdM);
		}

		// 根据累加值，建立坯料设计订单组成表
		long pdoiNo = 1;
		List<PlnDsnOrderInfo> lpdoiq = this.getMapper(PlnDsnOrderInfoMapper.class).findWithCondition(null, "",
				" serial_no desc", 0, 1);
		if (lpdoiq != null && lpdoiq.size() > 0) {
			pdoiNo = lpdoiq.get(0).getSerial_no() + 1;
		}

		// 建立虚拟子卷信息
		PlnMaterielDetail pmdc = new PlnMaterielDetail();
		pmdc.setSerial_no(PMDNo++);
		pmdc.setObject_no_vt(sDate + String.format("%06d", objectnoVtNo++));
		pmdc.setOrder_no(lpp.get(0).getOrder_no());
		pmdc.setStatus("0PDC10");
		pmdc.setIs_finished("0");
		pmdc.setPrev_dsn_process_code(processpoint.anneal_code);
		pmdc.setPrev_process_code(processpoint.anneal_code);
		pmdc.setIs_prev_dsn_finished("1");// 母卷：0
		pmdc.setCreate_design_no(pldm.getAn_design_no());
		pmdc.setCreate_process_code(processpoint.anneal_code);
		pmdc.setIs_mat(0);// 母卷：1
		pmdc.setOrder_no(lpp.get(0).getOrder_no());
		pmdc.setProd_order_no(lpp.get(0).getProd_order_no());
		pmdc.setAn_design_no(pldm.getAn_design_no());
		pmdc.setMat_object_no_vt(pmdM.getObject_no_vt());
		pmdc.setIs_multi("0");
		pmdc.setSteel_code(lpp.get(0).getSteel_code());
		pmdc.setWidth(pldmc.getWidth());
		pmdc.setThick(pldmc.getThick());
		pmdc.setLength(pldmc.getLength());
		pmdc.setDiameter_inn(pldmc.getDiameter_inn());
		pmdc.setDiameter_out(pldmc.getDiameter_out());

		// 母卷实重* 子卷计划宽度/母卷实宽
		pmdc.setSingle_weight(single_wgt);
		pmdc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
		pmdc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
		pmdc.setOrd_flg("1");
		pmdc.setCreate_man_name(userName);
		pmdc.setCreate_time(new Date());
		pmdc.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
		pmdc.setDeliver_date_latest(lpp.get(0).getDeliver_date());
		pmdc.setPk_ask_code(lpp.get(0).getPk_ask_code());
		pmdc.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
		this.getMapper(PlnMaterielDetailMapper.class).insert(pmdc);
		DesignInfo temp = new DesignInfo();
		temp.setObject_no_vt(pmdc.getObject_no_vt());
		temp.setSingle_wgt(pmdc.getSingle_weight());
		result.add(temp);

		// 订单组成信息
		PlnDsnOrderInfo pdoi = new PlnDsnOrderInfo();
		pdoi.setDesign_no(pldm.getAn_design_no());
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		pdoi.setWeight_in_one(single_wgt);
		pdoi.setQuantity_in_one(1);
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		if (obv_flg) {
			this.getMapper(PlnDsnOrderInfoMapper.class).doUpdate(pdoi);
		} else {
			pdoi.setSerial_no(pdoiNo++);
			pdoi.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnDsnOrderInfoMapper.class).insert(pdoi);
		}

//		// 修改生产订单进程表[PLN_PRODORDER_STATISTIC] 
//		PlnProdorderStatistic pps=new PlnProdorderStatistic();
//		pps.setProd_order_no(lpp.get(0).getProd_order_no());
//		if (proc_times ==1 ) {
//			pps.setAn_dsn(single_wgt);
//			pps.setAn_dsn_cnt(1);
//			pps.setMat_an_dsn(single_wgt); // 实物重量
//			pps.setMat_an_dsn_cnt(1); 
//			pps.setAn_undsn(single_wgt==null?null:(-single_wgt)); //实物重量
//		}else {
//			pps.setAn_dsn2(single_wgt);
//			pps.setAn_dsn_cnt2(1);
//			pps.setMat_an_dsn2(single_wgt); // 实物重量
//			pps.setMat_an_dsn_cnt2(1); 
//			pps.setAn_undsn2(single_wgt==null?null:(-single_wgt)); //实物重量
//		}
//		this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
//		
//		// 修改订单进程表[PLN_ORDER_STATISTIC]
//		PlnOrderStatistic pos=new PlnOrderStatistic();
//		pos.setOrder_no(lpp.get(0).getOrder_no());
//		if (proc_times ==1 ) {
//			pos.setAn_dsn(single_wgt);
//			pos.setAn_dsn_cnt(1);
//			pos.setMat_an_dsn(single_wgt); // 实物重量
//			pos.setMat_an_dsn_cnt(1); 
//			pos.setAn_undsn(single_wgt==null?null:(-single_wgt)); // 实物重量
//		}else {
//			pos.setAn_dsn2(single_wgt);
//			pos.setAn_dsn_cnt2(1);
//			pos.setMat_an_dsn2(single_wgt); // 实物重量
//			pos.setMat_an_dsn_cnt2(1); 
//			pos.setAn_undsn2(single_wgt==null?null:(-single_wgt)); // 实物重量
//		}
//		this.getMapper(PlnOrderStatisticMapper.class).doUpdateAnPlaned(pos);
		return result;
	}

	/**
	 * 酸洗设计信息
	 * 
	 * @param prod_order_no     生产订单号
	 * @param object_no_vt      虚拟母卷号
	 * @param prev_process_code 上道工序
	 * @param next_process_code 下道工序
	 * @param proc_times        生成主表设计信息、拼料信息、虚拟物料信息、订单组成信息
	 * @return
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public List<DesignInfo> PicklePlanDsn(String prod_order_no, String object_no_vt, String prev_process_code,
			String next_process_code, Double single_wgt, String object_no, Integer proc_times) {

		List<DesignInfo> result = new ArrayList<>();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		Double width = 0d;

		boolean obv_flg = false;
		// 获取虚拟母卷信息
		List<PlnMaterielDetail> pmdel = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			pmdel = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		if (Utils.isNotEmpty(pmdel) && pmdel.get(0).getPc_design_no() != null) {
			obv_flg = true;
		}
		// 获取订单信息
		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(prod_order_no);
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);
		if (Utils.isNotEmpty(pmdel)) {
			width = pmdel.get(0).getWidth();
		} else {
			width = lpp.get(0).getWidth();
		}
		// 计算所需原料卷数量
//		int db_cnt = (new BigDecimal(lpp.get(0).getEstimate_weight()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue() == 0 ? 1:(new BigDecimal(lpp.get(0).getEstimate_weight()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue();
		String sDate = new SimpleDateFormat("yyMMdd").format(new Date());
		PlnPickleDsnMain pldm = new PlnPickleDsnMain();

		// 设计信息存在就修改设计主表
		if (obv_flg) {
			// 设计主表不变
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(width);
			pldm.setLength(lpp.get(0).getLength());
			// 删除原有拼料信息
			pldm.setPc_design_no(pmdel.get(0).getPc_design_no());
			this.getMapper(PlnPickleDsnMultinfoMapper.class).doDelete(pmdel.get(0).getPc_design_no());
		} else {
			// 保存设计主表数据： 酸洗设计号：DPC+YYMMDD+6流水号
			List<PlnPickleDsnMain> lpdmNo = this.getMapper(PlnPickleDsnMainMapper.class).findWithCondition(null, "",
					" serial_no desc ", 0, 1);
			pldm.setSerial_no(1l);
			pldm.setPc_design_no("DPC" + sDate + String.format("%06d", 1));
			if (lpdmNo != null && lpdmNo.size() > 0) {
				pldm.setSerial_no(lpdmNo.get(0).getSerial_no() + 1);
				if (sDate.equals(lpdmNo.get(0).getPc_design_no().substring(3, 9))) {
					pldm.setPc_design_no("DPC" + sDate + String.format("%06d",
							Integer.parseInt(lpdmNo.get(0).getPc_design_no().substring(9, 15)) + 1));
				}
			}

			// 订单信息
			pldm.setProd_order_no(lpp.get(0).getProd_order_no());
			pldm.setOrder_no(lpp.get(0).getOrder_no());
			pldm.setPline_code(lpp.get(0).getPline_code());
			pldm.setSteel_code(lpp.get(0).getSteel_code());
			String isMulti = "0";// 是否拼料 根据订单数判断，多个订单填1，否则填0
			pldm.setIs_multi(isMulti);
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(width);
			pldm.setLength(lpp.get(0).getLength());
			pldm.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pldm.setDiameter_out(lpp.get(0).getDiameter_out());
			pldm.setSingle_weight(single_wgt);
//		pldm.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//		pldm.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pldm.setDeliver_date(lpp.get(0).getDeliver_date());
			pldm.setDesign_quantity(1);
			pldm.setDesign_weight(single_wgt); // 实物单重
			pldm.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pldm.setDeliver_date_latest(lpp.get(0).getDeliver_date());
//			pldm.setSub_count(1L);
			pldm.setCreate_man_name(userName);
			pldm.setCreate_time(new Date());
			pldm.setIs_finished(0L);
			pldm.setReserve_1(lpp.get(0).getProduce_no());
			this.getMapper(PlnPickleDsnMainMapper.class).insert(pldm);
		}

		// 倒叙取一条拼料信息
		List<PlnPickleDsnMultinfo> lpdmM = this.getMapper(PlnPickleDsnMultinfoMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long DsnNo = 1;
		if (lpdmM != null && lpdmM.size() > 0) {
			DsnNo = lpdmM.get(0).getSerial_no() + 1;
		}

		// -----------------写拼料信息-----------------------------
		PlnPickleDsnMultinfo pldmc = new PlnPickleDsnMultinfo();
		pldmc.setSerial_no(DsnNo);
		pldmc.setPc_design_no(pldm.getPc_design_no());
		pldmc.setSub_seq(1);
		pldmc.setOrder_no(lpp.get(0).getOrder_no());
		pldmc.setProd_order_no(lpp.get(0).getProd_order_no());
		pldmc.setThick(lpp.get(0).getThick());
		pldmc.setWidth(width);
		pldmc.setLength(lpp.get(0).getLength());
		pldmc.setDiameter_inn(lpp.get(0).getDiameter_inn());
		pldmc.setDiameter_out(lpp.get(0).getDiameter_out());
		pldmc.setWeight(single_wgt);
//		pldmc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
//		pldmc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
		pldmc.setSub_seq(1);
		this.getMapper(PlnPickleDsnMultinfoMapper.class).insert(pldmc);

		// 生成虚拟物料信息倒叙去一条
		List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long PMDNo = 1;
		if (lpmd != null && lpmd.size() > 0) {
			PMDNo = lpmd.get(0).getSerial_no() + 1;
		}
		int objectnoVtNo = this.getMapper(PlnMaterielDetailMapper.class).getObjectVtMaxNoForDate(sDate) + 1;

		List<PlnMaterielDetail> detail = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			detail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		// 虚拟母卷计划内的才需要新增或者修改
		PlnMaterielDetail pmdM = new PlnMaterielDetail();
		if (Utils.isNotEmpty(detail)) {
			pmdM = detail.get(0);
			pmdM.setStatus("0PDF10");
			if (Utils.isNotEmpty(object_no)) {
				pmdM.setObject_no(object_no);
			}
			pmdM.setNext_dsn_process_code(processpoint.pickle_code);
			pmdM.setNext_process_code(processpoint.pickle_code);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setPc_design_no(pldm.getPc_design_no());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			// 存在大批量脱单的时候，卷子虚拟物料信息的卷号信息没被清空，所以再次挂单的时候，选择直接更新订单号：
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnMaterielDetailMapper.class).update(pmdM);
		} else {
			pmdM.setSerial_no(PMDNo++);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setObject_no_vt(object_no_vt == null ? sDate + String.format("%06d", objectnoVtNo++) : object_no_vt);
			pmdM.setObject_no(object_no);
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setPline_code(lpp.get(0).getPline_code());
			pmdM.setStatus("0PDF10");
			pmdM.setIs_finished("0");
//			pmdM.setPrev_dsn_process_code(prev_process_code);
//			pmdM.setPrev_process_code(prev_process_code);
			pmdM.setNext_dsn_process_code(processpoint.pickle_code);
			pmdM.setNext_process_code(processpoint.pickle_code);
			pmdM.setIs_prev_dsn_finished("0");// 母卷：0
			pmdM.setCreate_design_no(pldm.getPc_design_no());
			pmdM.setCreate_process_code(processpoint.pickle_code);
			pmdM.setIs_mat(1);// 母卷：1
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setPc_design_no(pldm.getPc_design_no());
			pmdM.setIs_multi("0");
			pmdM.setSteel_code(lpp.get(0).getSteel_code());
			// 母卷厚度、宽度使用计划值
			pmdM.setWidth(width);
			pmdM.setThick(lpp.get(0).getThick());
			pmdM.setLength(lpp.get(0).getLength());
			pmdM.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pmdM.setDiameter_out(lpp.get(0).getDiameter_out());
			pmdM.setSingle_weight(single_wgt);
			pmdM.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdM.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdM.setOrd_flg("1");
			pmdM.setCreate_man_name(userName);
			pmdM.setCreate_time(new Date());
			pmdM.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdM.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdM);
		}

		// 根据累加值，建立坯料设计订单组成表
		long pdoiNo = 1;
		List<PlnDsnOrderInfo> lpdoiq = this.getMapper(PlnDsnOrderInfoMapper.class).findWithCondition(null, "",
				" serial_no desc", 0, 1);
		if (lpdoiq != null && lpdoiq.size() > 0) {
			pdoiNo = lpdoiq.get(0).getSerial_no() + 1;
		}

		// 建立虚拟子卷信息
		PlnMaterielDetail pmdc = new PlnMaterielDetail();
		pmdc.setSerial_no(PMDNo++);
		pmdc.setObject_no_vt(sDate + String.format("%06d", objectnoVtNo++));
		pmdc.setOrder_no(lpp.get(0).getOrder_no());
		pmdc.setStatus("0PDF10");
		pmdc.setIs_finished("0");
		pmdc.setPrev_dsn_process_code(processpoint.pickle_code);
		pmdc.setPrev_process_code(processpoint.pickle_code);
		pmdc.setIs_prev_dsn_finished("1");// 母卷：0
		pmdc.setCreate_design_no(pldm.getPc_design_no());
		pmdc.setCreate_process_code(processpoint.pickle_code);
		pmdc.setIs_mat(0);// 母卷：1
		pmdc.setOrder_no(lpp.get(0).getOrder_no());
		pmdc.setProd_order_no(lpp.get(0).getProd_order_no());
		pmdc.setPc_design_no(pldm.getPc_design_no());
		pmdc.setMat_object_no_vt(pmdM.getObject_no_vt());
		pmdc.setIs_multi("0");
		pmdc.setSteel_code(lpp.get(0).getSteel_code());
		pmdc.setWidth(pldmc.getWidth());
		pmdc.setThick(pldmc.getThick());
		pmdc.setLength(pldmc.getLength());
		pmdc.setDiameter_inn(pldmc.getDiameter_inn());
		pmdc.setDiameter_out(pldmc.getDiameter_out());
		pmdc.setSub_count(1);
		// 母卷实重* 子卷计划宽度/母卷实宽
		pmdc.setSingle_weight(single_wgt);
		pmdc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
		pmdc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
		pmdc.setOrd_flg("1");
		pmdc.setCreate_man_name(userName);
		pmdc.setCreate_time(new Date());
		pmdc.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
		pmdc.setDeliver_date_latest(lpp.get(0).getDeliver_date());
		pmdc.setPk_ask_code(lpp.get(0).getPk_ask_code());
		pmdc.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
		this.getMapper(PlnMaterielDetailMapper.class).insert(pmdc);
		DesignInfo temp = new DesignInfo();
		temp.setObject_no_vt(pmdc.getObject_no_vt());
		temp.setSingle_wgt(pmdc.getSingle_weight());
		result.add(temp);

		// 订单组成信息
		PlnDsnOrderInfo pdoi = new PlnDsnOrderInfo();
		pdoi.setDesign_no(pldm.getPc_design_no());
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		pdoi.setWeight_in_one(single_wgt);
		pdoi.setQuantity_in_one(1);
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		if (obv_flg) {
			this.getMapper(PlnDsnOrderInfoMapper.class).doUpdate(pdoi);
		} else {
			pdoi.setSerial_no(pdoiNo++);
			pdoi.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnDsnOrderInfoMapper.class).insert(pdoi);
		}
		return result;
	}

	/**
	 * 分条设计信息
	 * 
	 * @param prod_order_no     生产订单号
	 * @param object_no_vt      虚拟母卷号
	 * @param prev_process_code 上道工序
	 * @param next_process_code 下道工序 生成主表设计信息、拼料信息、虚拟物料信息、订单组成信息
	 *                          如果传入的虚拟物料信息存在设计号修改设计信息
	 *                          根据订单的厚度规格默认纵剪机台
	 *            3mm及以上默认大纵剪 else 小纵剪
	 *                      
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public List<DesignInfo> LengthwisePlanDsn(String prod_order_no, String object_no_vt, String prev_process_code,
			String next_process_code, Double single_wgt, String object_no, Integer proc_times) throws Exception {

		List<DesignInfo> result = new ArrayList<>();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);

		// 订单信息
		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(prod_order_no);
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);

		// 根据传入的生产订单号，读取生产订单对应的生产加工表[PLN_PROCESS_PLAN]
		PlnProcessPlan ppp = new PlnProcessPlan();
		ppp.setOrder_no(lpp.get(0).getOrder_no());
		ppp.setValid_flag("1");
		List<PlnProcessPlan> lppp = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(ppp, null,
				" cut_order_no ", 0, 0);
		if (lppp == null || lppp.size() == 0) {
			throw new Exception("未找到生产订单[" + ppp.getOrder_no() + "]对应的生产加工信息");
		}

		boolean obv_flg = false;
		// 母卷虚拟物料数据
		List<PlnMaterielDetail> detail = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			detail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		if (Utils.isNotEmpty(detail) && detail.get(0).getLw_design_no() != null) {
			obv_flg = true;
		}
		double sWidth = 0;
		int iCutCount = 0;
		for (PlnProcessPlan pppc : lppp) {
			sWidth += pppc.getWidth().doubleValue() * (pppc.getCut_num() == null ? 1 : pppc.getCut_num().intValue());
			iCutCount += (pppc.getCut_num() == null ? 1 : pppc.getCut_num().intValue());
		}
		PlnLengthwiseDsnMain pldm = new PlnLengthwiseDsnMain();
		String sDate = new SimpleDateFormat("yyMMdd").format(new Date());
		// 设计信息存在就修改设计主表(加工计划相关的信息)
		if (obv_flg) {
			pldm.setLw_design_no(detail.get(0).getLw_design_no());
			if (lppp.size() == 1) {
				pldm.setThick(lppp.get(0).getThick());
				pldm.setWidth(lppp.get(0).getWidth());
				pldm.setLength(lppp.get(0).getLength());
			}
			pldm.setSingle_weight(single_wgt);
			pldm.setDesign_weight(single_wgt);
			pldm.setMat_single_weight(single_wgt);
			pldm.setReserve_1(lppp.get(0).getProduce_no());
			pldm.setProd_rate(sWidth / lppp.get(0).getMat_width().doubleValue());
			pldm.setSub_count(iCutCount);
			pldm.setMat_thick(lppp.get(0).getThick());
			pldm.setMat_length(lppp.get(0).getLength());
			pldm.setMachine_code(lpp.get(0).getThick()>=3?"M0002":"M0001");
			if (!"1".equals(lpp.get(0).getOrder_nature()) && !"3".equals(lpp.get(0).getOrder_nature())
					&& "2".equals(lppp.get(0).getCut_type())) {
				pldm.setCut_style(lppp.get(0).getCut_style());
			}
			pldm.setCrosscut_style(lppp.get(0).getCrosscut_style());
			this.getMapper(PlnLengthwiseDsnMainMapper.class).updateDesInfoByNo(pldm);
			// 删除原有拼料信息
			this.getMapper(PlnLengthwiseDsnMultinfoMapper.class).doDelete(detail.get(0).getLw_design_no());
		} else {
			// 保存设计主表数据： 纵剪设计号：DLW+YYMMDD+6流水号
			List<PlnLengthwiseDsnMain> lpdmNo = this.getMapper(PlnLengthwiseDsnMainMapper.class).findWithCondition(null,
					"", " serial_no desc ", 0, 1);
			pldm.setSerial_no(1l);
			pldm.setLw_design_no("DLW" + sDate + String.format("%06d", 1));
			if (lpdmNo != null && lpdmNo.size() > 0) {
				pldm.setSerial_no(lpdmNo.get(0).getSerial_no() + 1);
				if (sDate.equals(lpdmNo.get(0).getLw_design_no().substring(3, 9))) {
					pldm.setLw_design_no("DLW" + sDate + String.format("%06d",
							Integer.parseInt(lpdmNo.get(0).getLw_design_no().substring(9, 15)) + 1));
				}
			}

			pldm.setProd_order_no(lpp.get(0).getProd_order_no());
			pldm.setOrder_no(lpp.get(0).getOrder_no());
			pldm.setPline_code(lpp.get(0).getPline_code());
			pldm.setSteel_code(lpp.get(0).getSteel_code());
			
			pldm.setMachine_code(lpp.get(0).getThick()>=3?"M0002":"M0001");
			
			String isMulti = "0";// 是否拼料 根据订单数判断，多个订单填1，否则填0
			pldm.setIs_multi(isMulti);
			pldm.setMat_diameter_inn(lpp.get(0).getDiameter_inn());
			pldm.setMat_diameter_out(lpp.get(0).getDiameter_out());
			pldm.setMat_single_weight(single_wgt);
			pldm.setMat_width(lpp.get(0).getWidth());
			pldm.setProd_rate(sWidth / lppp.get(0).getMat_width().doubleValue());
			pldm.setSub_count(iCutCount);
			pldm.setMat_thick(lppp.get(0).getThick());
			pldm.setMat_length(lppp.get(0).getLength());
			pldm.setSingle_weight(single_wgt);
			if (lppp.size() == 1) {
				pldm.setThick(lppp.get(0).getThick());
				pldm.setWidth(lppp.get(0).getWidth());
				pldm.setLength(lppp.get(0).getLength());
				pldm.setDiameter_inn(lpp.get(0).getDiameter_inn());
				pldm.setDiameter_out(lpp.get(0).getDiameter_out());
			}
			pldm.setSingle_weight(single_wgt);
			if (!"1".equals(lpp.get(0).getOrder_nature()) && !"3".equals(lpp.get(0).getOrder_nature())
					&& "2".equals(lppp.get(0).getCut_type())) {
				pldm.setCut_style(lppp.get(0).getCut_style());
			}

			pldm.setCrosscut_style(lppp.get(0).getCrosscut_style());
			pldm.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pldm.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pldm.setDeliver_date(lpp.get(0).getDeliver_date());
			pldm.setDesign_quantity(1);
			pldm.setDesign_weight(single_wgt);

			pldm.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pldm.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pldm.setCreate_man_name(userName);
			pldm.setCreate_time(new Date());
			pldm.setIs_finished(0);
			pldm.setReserve_1(lppp.get(0).getProduce_no());
			this.getMapper(PlnLengthwiseDsnMainMapper.class).insert(pldm);
		}
		// 倒叙取一条
		List<PlnLengthwiseDsnMultinfo> lpdmM = this.getMapper(PlnLengthwiseDsnMultinfoMapper.class)
				.findWithCondition(null, "", " serial_no desc ", 0, 1);
		long DsnNo = 1;
		if (lpdmM != null && lpdmM.size() > 0) {
			DsnNo = lpdmM.get(0).getSerial_no() + 1;
		}

		int iCrosscut = 0;
		if (Utils.isNotEmpty(lppp.get(0).getCrosscut_style()) && !"1".equals(lppp.get(0).getCrosscut_style())) {
			iCrosscut = Integer.parseInt(lppp.get(0).getCrosscut_style());
		} else {
			iCrosscut = 1;
		}

		int isubSeq = 1;
		for (int idx_hq = 1; idx_hq <= iCrosscut; idx_hq++) {
			int V_分条序号 = 1;
			for (PlnProcessPlan pppc : lppp) {
				for (int idx_sub = 1; idx_sub <= (pppc.getCut_num() == null ? 1
						: pppc.getCut_num().intValue()); idx_sub++) {
					// 其中：LW_SEQ 分条序号=V_分条序号; SEG_SEQ 分段序号=idx_hq;
					// -----------------写拼料信息-----------------------------
					PlnLengthwiseDsnMultinfo pldmc = new PlnLengthwiseDsnMultinfo();
					pldmc.setSerial_no(DsnNo++);
					pldmc.setLw_design_no(pldm.getLw_design_no());
					pldmc.setLw_seq(V_分条序号++);
					pldmc.setSeg_seq(idx_hq);
					pldmc.setOrder_no(lpp.get(0).getOrder_no());
					pldmc.setProd_order_no(lpp.get(0).getProd_order_no());
					pldmc.setThick(pppc.getThick());
					pldmc.setWidth(pppc.getWidth());
					pldmc.setLength(pppc.getLength());
					pldmc.setDiameter_inn(pppc.getDiameter_inn());
					pldmc.setDiameter_out(pppc.getDiameter_out());
					pldmc.setWeight(pldm.getSingle_weight().doubleValue() * pppc.getWidth().doubleValue()
							/ ((pppc.getWidth_total() == null ? pppc.getWidth().doubleValue()
									: pppc.getWidth_total().doubleValue())
									* Integer.parseInt(pldm.getCrosscut_style())));
					pldmc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
					pldmc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
					pldmc.setSub_seq(isubSeq++);
					pldmc.setPlan_no(pppc.getPlan_no());

					if (pldmc.getSub_seq() >= 1000 || pldmc.getLw_seq() >= 1000) {
						throw new Exception(
								"子卷序号[" + pldmc.getSub_seq() + "]和分条序号[" + pldmc.getLw_seq() + "]不在设备限制范围内！");
					}
					this.getMapper(PlnLengthwiseDsnMultinfoMapper.class).insert(pldmc);
				}
			}
		}

		// 建立虚拟物料表信息
		List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, null,
				" serial_no desc ", 0, 1);
		long PMDNo = lpmd == null ? 1 : (lpmd.size() == 0 ? 1 : (lpmd.get(0).getSerial_no() + 1));
		int objectnoVtNo = this.getMapper(PlnMaterielDetailMapper.class).getObjectVtMaxNoForDate(sDate) + 1;

		// 根据累加值，建立坯料设计订单组成表
		long pdoiNo = 1;
		List<PlnDsnOrderInfo> lpdoiq = this.getMapper(PlnDsnOrderInfoMapper.class).findWithCondition(null, "",
				" serial_no desc", 0, 1);
		if (lpdoiq != null && lpdoiq.size() > 0) {
			pdoiNo = lpdoiq.get(0).getSerial_no() + 1;
		}

		PlnMaterielDetail pmdM = new PlnMaterielDetail();
		if (Utils.isNotEmpty(detail)) {
			pmdM = detail.get(0);
			pmdM.setStatus("0PDA10");
			pmdM.setProc_repeat_index(proc_times);
			if (Utils.isNotEmpty(object_no)) {
				pmdM.setObject_no(object_no);
			}
			pmdM.setNext_dsn_process_code(processpoint.slitting_code);
			pmdM.setNext_process_code(processpoint.slitting_code);
			pmdM.setLw_design_no(pldm.getLw_design_no());
			pmdM.setMachine_code(lpp.get(0).getThick()>=3?"M0002":"M0001");
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			// 存在大批量脱单的时候，卷子虚拟物料信息的卷号信息没被清空，所以再次挂单的时候，选择直接更新订单号：
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnMaterielDetailMapper.class).update(pmdM);
		} else {
			pmdM.setMachine_code(lpp.get(0).getThick()>=3?"M0002":"M0001");
			pmdM.setSerial_no(PMDNo++);
			pmdM.setObject_no(object_no);
			pmdM.setObject_no_vt(object_no_vt == null ? sDate + String.format("%06d", objectnoVtNo++) : object_no_vt);
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setPline_code(lpp.get(0).getPline_code());
			pmdM.setStatus("0PDA10");
			pmdM.setIs_finished("0");
			pmdM.setProc_repeat_index(proc_times);
			// pmdM.setPrev_dsn_process_code(prev_process_code);
			// pmdM.setPrev_process_code(prev_process_code);
			pmdM.setNext_dsn_process_code(processpoint.slitting_code);
			pmdM.setNext_process_code(processpoint.slitting_code);
			pmdM.setIs_prev_dsn_finished("0");// 母卷：0
			pmdM.setCreate_design_no(pldm.getLw_design_no());
			pmdM.setCreate_process_code(processpoint.slitting_code);
			pmdM.setIs_mat(1);// 母卷：1
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setLw_design_no(pldm.getLw_design_no());
			pmdM.setIs_multi("0");
			pmdM.setSteel_code(lpp.get(0).getSteel_code());

			// 母卷厚度、宽度使用计划值
			pmdM.setWidth(lpp.get(0).getWidth());
			pmdM.setThick(lpp.get(0).getThick());
			pmdM.setLength(lpp.get(0).getLength());
			pmdM.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pmdM.setDiameter_out(lpp.get(0).getDiameter_out());
			pmdM.setSingle_weight(single_wgt);
			pmdM.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdM.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdM.setOrd_flg("1");
			pmdM.setCreate_man_name(userName);
			pmdM.setCreate_time(new Date());
			pmdM.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdM.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdM);
		}

		// 根据纵剪设计号，查找 纵剪拼料信息表[PLN_LENGTHWISE_DSN_MULTINFO]，循环读取每一子卷序号【SUB_SEQ】
		PlnLengthwiseDsnMultinfo multinfo = new PlnLengthwiseDsnMultinfo();
		multinfo.setLw_design_no(pldm.getLw_design_no());
		List<PlnLengthwiseDsnMultinfo> lpldm = this.getMapper(PlnLengthwiseDsnMultinfoMapper.class).find(multinfo, 0,
				0);
		double v_total_wgt = 0;
		int v_total_num = 0;
		// 2018-06-19 从加工计划取子卷宽度之和
		PlnProcessPlan ppplan = new PlnProcessPlan();
		double total_width = 0;
		ppplan.setProduce_no(lpp.get(0).getProduce_no());
		ppplan.setValid_flag("1");
		List<PlnProcessPlan> pprocess = this.getMapper(PlnProcessPlanMapper.class).find(ppplan, 0, 0);
		if (pprocess == null || pprocess.size() == 0) {
			throw new Exception("查找订单[" + lpp.get(0).getOrder_no() + "]的加工计划失败!");
		} else {
			for (PlnProcessPlan plnprocessplan : pprocess) {
				total_width += plnprocessplan.getWidth().doubleValue() * plnprocessplan.getCut_num();
			}
			if (total_width < 0.001) {
				throw new Exception("订单[" + lpp.get(0).getOrder_no() + "]的加工计划子卷宽度之和有误,不能小于0!");
			}
		}
		for (PlnLengthwiseDsnMultinfo pldmc : lpldm) {
			// 建立虚拟子卷信息
			PlnMaterielDetail pmdc = new PlnMaterielDetail();
			pmdc.setSerial_no(PMDNo++);
			pmdc.setObject_no_vt(sDate + String.format("%06d", objectnoVtNo++));
			pmdc.setOrder_no(lpp.get(0).getOrder_no());
			pmdc.setStatus("0PDA10");
			pmdc.setIs_finished("0");
			pmdc.setPrev_dsn_process_code(processpoint.slitting_code);
			pmdc.setPrev_process_code(processpoint.slitting_code);
			pmdc.setCreate_design_no(pldm.getLw_design_no());
			pmdc.setCreate_process_code(processpoint.slitting_code);
			pmdc.setIs_mat(0);// 母卷：1
			pmdc.setOrder_no(lpp.get(0).getOrder_no());
			pmdc.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdc.setLw_design_no(pldm.getLw_design_no());
			pmdc.setMat_object_no_vt(pmdM.getObject_no_vt());
			pmdc.setIs_multi("0");
			pmdc.setSteel_code(lpp.get(0).getSteel_code());
			pmdc.setWidth(pldmc.getWidth());
			pmdc.setThick(pldmc.getThick());
			pmdc.setLength(pldmc.getLength());
			pmdc.setDiameter_inn(pldmc.getDiameter_inn());
			pmdc.setDiameter_out(pldmc.getDiameter_out());

			// 母卷实重* 子卷计划宽度/母卷实宽
//			pmdc.setSingle_weight(pmdM.getSingle_weight().doubleValue()*pldmc.getWidth().doubleValue()/(total_width*Integer.parseInt(lppp.get(0).getCrosscut_style())));
			pmdc.setSingle_weight(new BigDecimal(pmdM.getSingle_weight().doubleValue() * pldmc.getWidth().doubleValue()
					/ (total_width * Integer.parseInt(lppp.get(0).getCrosscut_style())))
							.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
			pmdc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdc.setOrd_flg("1");
			pmdc.setCreate_man_name(userName);
			pmdc.setCreate_time(new Date());
			pmdc.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdc.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdc.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdc.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			pmdc.setPlan_no(pldmc.getPlan_no());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdc);
			DesignInfo temp = new DesignInfo();
			// 累加虚拟子卷重量，虚拟子卷个数
			v_total_wgt += pmdc.getSingle_weight().doubleValue();
			v_total_num += 1;
			temp.setObject_no_vt(pmdc.getObject_no_vt());
			temp.setSingle_wgt(pmdc.getSingle_weight());
			result.add(temp);
		}

		PlnDsnOrderInfo pdoi = new PlnDsnOrderInfo();
		pdoi.setDesign_no(pldm.getLw_design_no());
		pdoi.setWeight_in_one(v_total_wgt);
		pdoi.setQuantity_in_one(v_total_num);
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		if (obv_flg) {
			this.getMapper(PlnDsnOrderInfoMapper.class).doUpdate(pdoi);
		} else {
			pdoi.setSerial_no(pdoiNo++);
			pdoi.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnDsnOrderInfoMapper.class).insert(pdoi);
		}

//		//修改生产订单进程表[PLN_PRODORDER_STATISTIC]
//		PlnProdorderStatistic pps=new PlnProdorderStatistic();
//		pps.setProd_order_no(lpp.get(0).getProd_order_no());
//		pps.setLw_dsn(v_total_wgt);
//		pps.setLw_dsn_cnt(v_total_num);
//		pps.setMat_lw_dsn(single_wgt); // 实物重量
//		pps.setMat_lw_dsn_cnt(1);
//		pps.setLw_undsn(single_wgt == null ? null : (-single_wgt)); // 实物重量
//		this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
//		
//		
//		//修改订单进程表[PLN_ORDER_STATISTIC]
//		PlnOrderStatistic pos=new PlnOrderStatistic();
//		pos.setOrder_no(lpp.get(0).getOrder_no());
//		pos.setLw_dsn(v_total_wgt);
//		pos.setLw_dsn_cnt(v_total_num);
//		pos.setMat_lw_dsn(single_wgt); // 实物重量
//		pos.setMat_lw_dsn_cnt(1); 
//		pos.setLw_undsn(single_wgt==null?null:(-single_wgt)); // 实物重量
//		this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
		return result;
	}

	/**
	 * 开平设计信息
	 * 
	 * @param prod_order_no     生产订单号
	 * @param object_no_vt      虚拟母卷号
	 * @param prev_process_code 上道工序
	 * @param next_process_code 下道工序 生成主表设计信息、拼料信息、虚拟物料信息、订单组成信息
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public List<DesignInfo> CuttolengthPlanDsn(String prod_order_no, String object_no_vt, String prev_process_code,
			String next_process_code, Double single_wgt, String object_no, Integer proc_times) throws Exception {
		List<DesignInfo> result = new ArrayList<>();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);

		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(prod_order_no);
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).findWithCondition(pp, "",
				" create_time desc ", 0, 1);

		// 读取基础配置 产线机组限制表
		ComDsnPltlmt cdp = new ComDsnPltlmt();
		cdp.setPlt("Y1");// 工厂
		cdp.setPlt_line("Y1");// 产线
		List<ComDsnPltlmt> lc = this.getMapper(ComDsnPltlmtMapper.class).find(cdp, 0, 0);
		if (lc == null || lc.size() == 0) {
			throw new Exception("未找到产线");
		}
		// 获取所有的限制条件
		ClRestrict MachineRestrict = new ClRestrict(lc);

		// 根据加工计划号 读取生产订单对应的生产加工表[PLN_PROCESS_PLAN]
		PlnProcessPlan ppp = new PlnProcessPlan();
		ppp.setProduce_no(lpp.get(0).getProduce_no());
		ppp.setValid_flag("1");
		List<PlnProcessPlan> lppp = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(ppp, null,
				" cut_order_no ", 0, 0);
		if (lppp == null || lppp.size() == 0) {
			throw new Exception("未找到生产订单[" + ppp.getOrder_no() + "]对应的生产加工信息");
		}

		double sWidth = 0,
				// 每个规格下总堆垛数
				allboxCount = 0,
				// 重量上限
				weightupper = 0,
				// 临时-重量
				weighttemp = 0,
				// 单堆垛重量
				V_singleWeight = 0,
				// 单堆垛块数
				boxCount,
				// 该规格最后一堆,块数
				V_lastbox_Count = 0;
		// 总堆垛数/子板总数
		int iCutCount = 0, allsubcount = 0;
		// 加工计划号:单堆垛块数
		Map<String, Double> boxCounts = new HashMap<String, Double>();
		// 加工计划号:子堆垛数
		Map<String, Double> ZddCount = new HashMap<String, Double>();
		// 加工计划号:最后一堆.堆垛块数
		Map<String, Double> Last_Count = new HashMap<String, Double>();
		String cut_style = "";
		for (PlnProcessPlan pppc : lppp) {
			if (pppc.getMono_stack_max_weight() == null || pppc.getMono_stack_max_weight() == 0) {
				weightupper = 99999;
			} else {
				weightupper = pppc.getMono_stack_max_weight();
			}
			if (MachineRestrict.lim_max_box_wgt == 0) {
				weighttemp = 99999;
			} else {
				weighttemp = MachineRestrict.lim_max_box_wgt;
			}
			weightupper = weightupper > weighttemp ? weighttemp : weightupper;
			// 如果销售加工计划传入了计划块数
			if (pppc.getCut_num() != null && pppc.getCut_num() > 1) {
				// 总堆垛数
				allboxCount = Math.ceil(1.0 * pppc.getCut_num() * pppc.getThick() / MachineRestrict.lim_max_box_height);
				// 单堆垛块数
				boxCount = new BigDecimal(pppc.getCut_num() / allboxCount).setScale(0, BigDecimal.ROUND_HALF_UP)
						.doubleValue();
				// 单堆垛重量
				V_singleWeight = boxCount * GetWeightBySize(pppc.getThick(), pppc.getWidth(), pppc.getLength());
				if (V_singleWeight > weightupper) {
					boxCount = Math
							.ceil(weightupper / GetWeightBySize(pppc.getThick(), pppc.getWidth(), pppc.getLength()));
					allboxCount = Math.ceil(pppc.getCut_num() / boxCount);
				}
				V_lastbox_Count = pppc.getCut_num() - (allboxCount - 1) * boxCount;
				Last_Count.put(pppc.getPlan_no(), V_lastbox_Count);
			} else {
				// 子板重量
				double weigth = GetWeightBySize(pppc.getThick(), pppc.getWidth(), pppc.getLength());
				// 根据加工计划计算 堆垛总数= 向上取整(估算重量/单垛重量上限)；
				allboxCount = Math.ceil(single_wgt / weightupper);
				// 根据 堆垛数 反推 单堆垛块数 =(四舍五入) [估算重量/总堆垛数/(7.85*(10^-6)*厚*宽*长)];
				boxCount = new BigDecimal(single_wgt / allboxCount / weigth).setScale(0, BigDecimal.ROUND_HALF_UP)
						.doubleValue();
				// 如果 单堆垛块数 * 厚度 > 设备限制高度，则重新计算:
				if (boxCount * pppc.getThick().doubleValue() > MachineRestrict.lim_max_box_height) {
					// 单堆垛块数_临时= [四舍五入](设备限制高度/厚度)；
					boxCount = new BigDecimal(MachineRestrict.lim_max_box_height / pppc.getThick())
							.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
					// 堆垛总数 = (向上取整)[估算重量/(7.85*(10^-6)*厚*宽*长)* 单堆垛块数_临时]；
					allboxCount = Math.ceil(single_wgt / (weigth * boxCount));
					// 单堆垛块数 =(四舍五入) [估算重量/总堆垛数/(7.85*(10^-6)*厚*宽*长)];
					boxCount = new BigDecimal(single_wgt / allboxCount / weigth).setScale(0, BigDecimal.ROUND_HALF_UP)
							.doubleValue();
				}
			}
			sWidth += pppc.getWidth().doubleValue() * allboxCount * boxCount;
			allsubcount += allboxCount * boxCount;
			iCutCount += allboxCount;
			boxCounts.put(pppc.getPlan_no(), boxCount);
			ZddCount.put(pppc.getPlan_no(), allboxCount);
			cut_style += allboxCount + "*" + boxCount + "*";
		}

		boolean obv_flg = false;
		// 母卷虚拟物料数据
		List<PlnMaterielDetail> detail = null;
		if (Utils.isNotEmpty(object_no_vt)) {
			detail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
		}

		if (Utils.isNotEmpty(detail) && detail.get(0).getCl_design_no() != null) {
			obv_flg = true;
		}

		String sDate = new SimpleDateFormat("yyMMdd").format(new Date());
		PlnCuttolengthDsnMain pldm = new PlnCuttolengthDsnMain();

		// 设计信息存在就修改设计主表(加工计划相关的信息)
		if (obv_flg) {
			pldm.setCl_design_no(detail.get(0).getCl_design_no());
			if (lppp.size() == 1) {
				pldm.setThick(lppp.get(0).getThick());
				pldm.setWidth(lppp.get(0).getWidth());
				pldm.setLength(lppp.get(0).getLength());
			}
			pldm.setSingle_weight(single_wgt);
			pldm.setDesign_weight(single_wgt);
			pldm.setMat_single_weight(single_wgt);
			pldm.setReserve_1(lppp.get(0).getProduce_no());
			pldm.setProd_rate(sWidth / lppp.get(0).getMat_width().doubleValue());
			pldm.setSub_count(iCutCount);
			pldm.setMat_thick(lppp.get(0).getThick());
			pldm.setMat_length(lppp.get(0).getLength());
			if (!"1".equals(lpp.get(0).getOrder_nature()) && !"3".equals(lpp.get(0).getOrder_nature())
					&& "1".equals(lppp.get(0).getCut_type())) {
				pldm.setCut_style(lppp.get(0).getCut_style());
			}
			pldm.setPlate_count(allsubcount);
			this.getMapper(PlnCuttolengthDsnMainMapper.class).updateDesInfoByNo(pldm);
			// 删除原有拼料信息
			PlnCuttolengthDsnMultinfo pldmdd = new PlnCuttolengthDsnMultinfo();
			pldmdd.setCl_design_no(detail.get(0).getCl_design_no());
			this.getMapper(PlnCuttolengthDsnMultinfoMapper.class).doDelete(pldmdd);
		} else {
			// 保存设计主表数据： 横剪设计号：DCL+YYMMDD+6流水号
			List<PlnCuttolengthDsnMain> lpdmNo = this.getMapper(PlnCuttolengthDsnMainMapper.class)
					.findWithCondition(null, "", " to_number(serial_no) desc ", 0, 1);
			pldm.setCl_design_no("DCL" + sDate + String.format("%06d", 1));
			pldm.setSerial_no("1");
			if (lpdmNo != null && lpdmNo.size() > 0) {
				pldm.setSerial_no(String.valueOf(Integer.parseInt(lpdmNo.get(0).getSerial_no()) + 1));
				if (sDate.equals(lpdmNo.get(0).getCl_design_no().substring(3, 9))) {
					pldm.setCl_design_no("DCL" + sDate + String.format("%06d",
							Integer.parseInt(lpdmNo.get(0).getCl_design_no().substring(9, 15)) + 1));
				}
			}

			pldm.setProd_order_no(lpp.get(0).getProd_order_no());
			pldm.setOrder_no(lpp.get(0).getOrder_no());
			pldm.setPline_code(lpp.get(0).getPline_code());
			pldm.setSteel_code(lpp.get(0).getSteel_code());

			String isMulti = "0";// 是否拼料 根据订单数判断，多个订单填1，否则填0
			pldm.setIs_multi(isMulti);
			pldm.setMat_diameter_inn(lpp.get(0).getDiameter_inn());
			pldm.setMat_diameter_out(lpp.get(0).getDiameter_out());
			pldm.setMat_single_weight(single_wgt);
			pldm.setMat_width(lpp.get(0).getWidth());
			pldm.setProd_rate(sWidth / lppp.get(0).getMat_width().doubleValue());
			// 堆垛总数
			pldm.setSub_count(iCutCount);
			// 钢板总数
			pldm.setPlate_count(allsubcount);
			pldm.setMat_thick(lpp.get(0).getThick());
			pldm.setMat_length(lpp.get(0).getLength());
			pldm.setSingle_weight(single_wgt);
			if (lppp.size() == 1) {
				pldm.setThick(lppp.get(0).getThick());
				pldm.setWidth(lppp.get(0).getWidth());
				pldm.setLength(lppp.get(0).getLength());
				pldm.setDiameter_inn(lpp.get(0).getDiameter_inn());
				pldm.setDiameter_out(lpp.get(0).getDiameter_out());
				pldm.setSingle_weight(single_wgt);
			}

			// 需加工订单加工计划类型为开平
			if (!"1".equals(lpp.get(0).getOrder_nature()) && !"3".equals(lpp.get(0).getOrder_nature())
					&& "1".equals(lppp.get(0).getCut_type())) {
				pldm.setCut_style(lppp.get(0).getCut_style());
			}

			pldm.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pldm.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pldm.setDeliver_date(lpp.get(0).getDeliver_date());
			pldm.setDesign_quantity(1);
			pldm.setDesign_weight(single_wgt);

			pldm.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pldm.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pldm.setCreate_man_name(userName);
			pldm.setCreate_time(new Date());
			pldm.setIs_finished(0l);
			pldm.setReserve_1(lppp.get(0).getProduce_no());
			this.getMapper(PlnCuttolengthDsnMainMapper.class).insert(pldm);
		}
		// 倒叙取一条
		List<PlnCuttolengthDsnMultinfo> lpdmM = this.getMapper(PlnCuttolengthDsnMultinfoMapper.class)
				.findWithCondition(null, "", " to_number (serial_no) desc ", 0, 1);
		long DsnNo = 1;
		int sub_seq = 1;
		if (lpdmM != null && lpdmM.size() > 0) {
			DsnNo = lpdmM.get(0).getSerial_no() + 1;
		}
		// -----------------写拼料(单个堆垛的信息)-------------------------

		for (PlnProcessPlan pppc : lppp) {
			for (int idx_sub = 1; idx_sub <= ZddCount.get(pppc.getPlan_no()).intValue(); idx_sub++) {
				PlnCuttolengthDsnMultinfo pldmc = new PlnCuttolengthDsnMultinfo();
				pldmc.setSerial_no(DsnNo++);
				// 子堆垛序号
				pldmc.setSub_seq(sub_seq++);
				pldmc.setCl_design_no(pldm.getCl_design_no());
				pldmc.setOrder_no(lpp.get(0).getOrder_no());
				pldmc.setProd_order_no(lpp.get(0).getProd_order_no());
				// 堆垛规格
				pldmc.setThick(pppc.getThick() * boxCounts.get(pppc.getPlan_no()).intValue());
				pldmc.setWidth(pppc.getWidth());
				pldmc.setLength(pppc.getLength());
				// 子板规格
				pldmc.setSub_thick(pppc.getThick());
				pldmc.setSub_length(pppc.getLength());
				pldmc.setSub_width(pppc.getWidth());
				// 关联加工计划取唯一加工计划
				pldmc.setPlan_no(pppc.getPlan_no());
				// 如果传入了规格总块数,按块数来算
				if (pppc.getCut_num() != null && pppc.getCut_num() > 1
						&& ZddCount.get(pppc.getPlan_no()).intValue() > 1) {
					if (idx_sub == ZddCount.get(pppc.getPlan_no()).intValue()) {
						// sub_count 最后一剁子板总数
						pldmc.setSub_count(Last_Count.get(pppc.getPlan_no()).intValue());
						// 总数*单重
						pldmc.setWeight(
								new BigDecimal(GetWeightBySize(pppc.getThick(), pppc.getWidth(), pppc.getLength())
										* Last_Count.get(pppc.getPlan_no()).intValue())
												.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
					} else {
						// sub_count 子板总数
						pldmc.setSub_count(boxCounts.get(pppc.getPlan_no()).intValue());
						// 总数*单重
						pldmc.setWeight(
								new BigDecimal(GetWeightBySize(pppc.getThick(), pppc.getWidth(), pppc.getLength())
										* boxCounts.get(pppc.getPlan_no()).intValue())
												.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());

					}
				} else {
					// sub_count 子板总数
					pldmc.setSub_count(boxCounts.get(pppc.getPlan_no()).intValue());
					// 总数*单重
					pldmc.setWeight(new BigDecimal(GetWeightBySize(pppc.getThick(), pppc.getWidth(), pppc.getLength())
							* boxCounts.get(pppc.getPlan_no()).intValue()).setScale(3, BigDecimal.ROUND_HALF_UP)
									.doubleValue());
				}
				// 子板单重
				pldmc.setSub_weight(new BigDecimal(GetWeightBySize(pppc.getThick(), pppc.getWidth(), pppc.getLength()))
						.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
				// 定尺方式/切边方式
				pldmc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
				pldmc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());

				if (pldmc.getSub_seq() >= 1000) {
					throw new Exception("子板序号[" + pldmc.getSub_seq() + "]不在设备限制范围内！");
				}
				this.getMapper(PlnCuttolengthDsnMultinfoMapper.class).insert(pldmc);
			}
		}

		// 建立虚拟物料表信息
		List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, null,
				" serial_no desc ", 0, 1);
		long PMDNo = lpmd == null ? 1 : (lpmd.size() == 0 ? 1 : (lpmd.get(0).getSerial_no() + 1));
		int objectnoVtNo = this.getMapper(PlnMaterielDetailMapper.class).getObjectVtMaxNoForDate(sDate) + 1;

		// 根据累加值，建立坯料设计订单组成表
		long pdoiNo = 1;
		List<PlnDsnOrderInfo> lpdoiq = this.getMapper(PlnDsnOrderInfoMapper.class).findWithCondition(null, "",
				" serial_no desc", 0, 1);
		if (lpdoiq != null && lpdoiq.size() > 0) {
			pdoiNo = lpdoiq.get(0).getSerial_no() + 1;
		}

		PlnMaterielDetail pmdM = new PlnMaterielDetail();
		if (Utils.isNotEmpty(detail)) {
			pmdM = detail.get(0);
			pmdM.setStatus("0PDB10");
			if (Utils.isNotEmpty(object_no)) {
				pmdM.setObject_no(object_no);
			}
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setNext_dsn_process_code(processpoint.cross_cutting_code);
			pmdM.setNext_process_code(processpoint.cross_cutting_code);
			pmdM.setCl_design_no(pldm.getCl_design_no());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			// 存在大批量脱单的时候，卷子虚拟物料信息的卷号信息没被清空，所以再次挂单的时候，选择直接更新订单号：
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnMaterielDetailMapper.class).update(pmdM);
		} else {
			pmdM.setSerial_no(PMDNo++);
			pmdM.setObject_no_vt(sDate + String.format("%06d", objectnoVtNo++));
			pmdM.setObject_no(object_no);
			pmdM.setProc_repeat_index(proc_times);
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setPline_code(lpp.get(0).getPline_code());
			pmdM.setStatus("0PDB10");
			pmdM.setIs_finished("1");// 母卷：1
			// pmdM.setPrev_dsn_process_code(prev_process_code);
			// pmdM.setPrev_process_code(prev_process_code);
			pmdM.setNext_dsn_process_code(processpoint.cross_cutting_code);
			pmdM.setNext_process_code(processpoint.cross_cutting_code);

			pmdM.setCreate_design_no(pldm.getCl_design_no());
			pmdM.setCreate_process_code(processpoint.cross_cutting_code);
			pmdM.setIs_mat(1);// 母卷：1
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setCl_design_no(pldm.getCl_design_no());
			pmdM.setIs_multi("0");
			pmdM.setSteel_code(lpp.get(0).getSteel_code());
			// 母卷填库存实际值
			pmdM.setWidth(lpp.get(0).getWidth());
			pmdM.setThick(lpp.get(0).getThick());
			pmdM.setLength(lpp.get(0).getLength());
			pmdM.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pmdM.setDiameter_out(lpp.get(0).getDiameter_out());
			pmdM.setSingle_weight(single_wgt);
			pmdM.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdM.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdM.setOrd_flg("1");
			pmdM.setCreate_man_name(userName);
			pmdM.setCreate_time(new Date());
			pmdM.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdM.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdM.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdM.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdM);
		}
		// 根据横剪设计号，查找 横剪拼料信息表[PLN_Cuttolength_DSN_MULTINFO]，循环读取每一子卷序号【SUB_SEQ】
		PlnCuttolengthDsnMultinfo pldmm = new PlnCuttolengthDsnMultinfo();
		pldmm.setCl_design_no(pldm.getCl_design_no());
		List<PlnCuttolengthDsnMultinfo> lpldm = this.getMapper(PlnCuttolengthDsnMultinfoMapper.class).find(pldmm, 0, 0);
		double v_total_wgt = 0;
		int v_total_num = 0;

		for (PlnCuttolengthDsnMultinfo pldmc : lpldm) {
			// 建立虚拟子卷信息
			PlnMaterielDetail pmdc = new PlnMaterielDetail();
			pmdc.setSerial_no(PMDNo++);
			pmdc.setObject_no_vt(sDate + String.format("%06d", objectnoVtNo++));
			pmdc.setOrder_no(lpp.get(0).getOrder_no());
			pmdc.setPline_code(lpp.get(0).getPline_code());
			pmdc.setStatus("0PDB10");
			pmdc.setIs_finished("0");
			pmdc.setPrev_dsn_process_code(processpoint.cross_cutting_code);
			pmdc.setPrev_process_code(processpoint.cross_cutting_code);
			pmdc.setIs_prev_dsn_finished("1");
			pmdc.setCreate_design_no(pldm.getCl_design_no());
			pmdc.setCreate_process_code(processpoint.cross_cutting_code);
			pmdc.setIs_mat(0);// 母卷：1
			pmdc.setOrder_no(lpp.get(0).getOrder_no());
			pmdc.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdc.setCl_design_no(pldm.getCl_design_no());
			pmdc.setMat_object_no_vt(pmdM.getObject_no_vt());
			pmdc.setIs_multi("0");
			pmdc.setSteel_code(lpp.get(0).getSteel_code());
			// 计划值
			pmdc.setWidth(pldmc.getWidth());
			// 母卷厚度
			pmdc.setThick(pmdM.getThick());
			pmdc.setLength(pldmc.getLength());
			// 堆垛重量保留一位小数
			pmdc.setSingle_weight(pldmc.getWeight());
			// 预估堆垛的子板总数/单量
			pmdc.setSub_count(pldmc.getSub_count());
			pmdc.setSub_weight(pldmc.getSub_weight());
			pmdc.setSingle_weight(pldmc.getSub_weight());
			pmdc.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
			pmdc.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
			pmdc.setOrd_flg("1");
			pmdc.setCreate_man_name(userName);
			pmdc.setCreate_time(new Date());
			pmdc.setDeliver_date_earliest(lpp.get(0).getDeliver_date());
			pmdc.setDeliver_date_latest(lpp.get(0).getDeliver_date());
			pmdc.setPk_ask_code(lpp.get(0).getPk_ask_code());
			pmdc.setPk_ask_desc(lpp.get(0).getPk_ask_desc());
			pmdc.setPlan_no(pldmc.getPlan_no());
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdc);

			// 累加虚拟子堆垛重量，虚拟堆垛个数
			v_total_wgt += pmdc.getSingle_weight().doubleValue();
			v_total_num += 1;
			DesignInfo temp = new DesignInfo();
			temp.setObject_no_vt(pmdc.getObject_no_vt());
			temp.setSingle_wgt(pmdc.getSingle_weight());
			result.add(temp);
		}

		PlnDsnOrderInfo pdoi = new PlnDsnOrderInfo();
		pdoi.setDesign_no(pldm.getCl_design_no());
		pdoi.setProd_order_no(lpp.get(0).getProd_order_no());
		pdoi.setWeight_in_one(v_total_wgt);
		pdoi.setQuantity_in_one(v_total_num);
		// 坯料设计订单组成表
		if (obv_flg) {
			this.getMapper(PlnDsnOrderInfoMapper.class).doUpdate(pdoi);
		} else {
			pdoi.setSerial_no(pdoiNo++);
			pdoi.setOrder_no(lpp.get(0).getOrder_no());
			this.getMapper(PlnDsnOrderInfoMapper.class).insert(pdoi);
		}

//		//修改生产订单进程表[PLN_PRODORDER_STATISTIC]
//		PlnProdorderStatistic pps=new PlnProdorderStatistic();
//		pps.setProd_order_no(lpp.get(0).getProd_order_no());
//		pps.setCl_dsn(v_total_wgt);
//		pps.setCl_dsn_cnt(v_total_num);
//		pps.setMat_cl_dsn(single_wgt);
//		pps.setMat_cl_dsn_cnt(1);
//		pps.setCl_undsn(single_wgt==null?null:(-single_wgt.doubleValue()));//实物重量
//		this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
//		
//		
//		//修改订单进程表[PLN_ORDER_STATISTIC]
//		PlnOrderStatistic pos=new PlnOrderStatistic();
//		pos.setOrder_no(lpp.get(0).getOrder_no());
//		pos.setCl_dsn(v_total_wgt);
//		pos.setCl_dsn_cnt(v_total_num);
//		pos.setMat_cl_dsn(single_wgt);
//		pos.setMat_cl_dsn_cnt(1);
//		pos.setCl_undsn(single_wgt==null?null:(-single_wgt));//实物重量
//		this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
		return result;
	}

	/**
	 * 返回子卷参数信息
	 * 
	 * @param result 虚拟物料号集合
	 * @param info   当前操作参数对象
	 * @return
	 */
	public List<DesignInfo> GetChildParam(List<DesignInfo> result, DesignInfo info) {
		List<DesignInfo> infons = new ArrayList<DesignInfo>();
		if (result.size() == 1) {
			info.setObject_no_vt(result.get(0).getObject_no_vt());
			info.setSingle_wgt(result.get(0).getSingle_wgt());
			info.setObject_no(null);
			infons.add(info);
		} else {
			for (DesignInfo str : result) {
				DesignInfo di = new DesignInfo();
				di.setCurrentProcIndex(info.getCurrentProcIndex());
				di.setObject_no_vt(str.getObject_no_vt());
				di.setSingle_wgt(str.getSingle_wgt());
				di.setProcess(info.getProcess());
				di.setProd_order_no(info.getProd_order_no());
				infons.add(di);
			}
		}
		return infons;
	}

	/**
	 * 根据厚宽长获取重量
	 * 
	 * @param thick
	 * @param width
	 * @param length 注意单位都是毫米（传入）
	 * @return
	 */
	public static double GetWeightBySize(double thick, double width, double length) {
		return thick * width * length * 7.85 * Math.pow(10, -6);
	}

	/**
	 * 修改订单进程信息
	 * 
	 * @param prod_order_no
	 * @param order_no
	 * @param path
	 * @param single_wgt
	 * @param flag          true 挂单 false 脱单
	 */
	public void updateOrderStatic(String prod_order_no, String order_no, String path, Double single_wgt, boolean flag) {

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		int i = -1;
		Double wgt = -single_wgt;
		if (flag) {
			i = 1;
			wgt = single_wgt;
		}
		// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
		PlnProdorderStatistic pps = new PlnProdorderStatistic();
		pps.setProd_order_no(prod_order_no);
		if (path.contains(processpoint.anneal_code)) {
			String process_code = StringUtils.substringAfter(path, processpoint.anneal_code);
			pps.setAn_dsn(wgt);
			pps.setAn_dsn_cnt(i);
			pps.setMat_an_dsn(wgt); // 实物重量
			pps.setMat_an_dsn_cnt(i);
			pps.setAn_undsn(wgt == null ? null : (-wgt)); // 实物重量

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(order_no);
			pos.setAn_dsn(wgt);
			pos.setAn_dsn_cnt(i);
			pos.setMat_an_dsn(wgt); // 实物重量
			pos.setMat_an_dsn_cnt(i);
			pos.setAn_undsn(wgt == null ? null : (-wgt)); // 实物重量

			// 存在第二个罩退
			if (process_code.contains(processpoint.anneal_code)) {
				pps.setAn_dsn2(wgt);
				pps.setAn_dsn_cnt2(i);
				pps.setMat_an_dsn2(wgt); // 实物重量
				pps.setMat_an_dsn_cnt2(i);
				pps.setAn_undsn2(wgt == null ? null : (-wgt)); // 实物重量
				// 修改订单进程表[PLN_ORDER_STATISTIC]
				pos.setAn_dsn2(wgt);
				pos.setAn_dsn_cnt2(i);
				pos.setMat_an_dsn2(wgt); // 实物重量
				pos.setMat_an_dsn_cnt2(i);
				pos.setAn_undsn2(wgt == null ? null : (-wgt)); // 实物重量
			}
			this.getMapper(PlnOrderStatisticMapper.class).doUpdateAnPlaned(pos);
		}
		if (path.contains(processpoint.slitting_code)) {
			// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
			pps.setLw_dsn(wgt);
//			pps.setLw_dsn_cnt(v_total_num);
			pps.setMat_lw_dsn(wgt); // 实物重量
			pps.setMat_lw_dsn_cnt(i);
			pps.setLw_undsn(wgt == null ? null : (-wgt)); // 实物重量
//			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(order_no);
			pos.setLw_dsn(wgt);
//			pos.setLw_dsn_cnt(v_total_num);
			pos.setMat_lw_dsn(wgt); // 实物重量
			pos.setMat_lw_dsn_cnt(i);
			pos.setLw_undsn(wgt == null ? null : (-wgt)); // 实物重量
			this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
		}
		if (path.contains(processpoint.cross_cutting_code)) {
			// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
			pps.setCl_dsn(wgt);
//			pps.setCl_dsn_cnt(v_total_num);
			pps.setMat_cl_dsn(wgt);
			pps.setMat_cl_dsn_cnt(i);
			pps.setCl_undsn(wgt == null ? null : (-wgt.doubleValue()));// 实物重量
//			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(order_no);
			pos.setCl_dsn(wgt);
//			pos.setCl_dsn_cnt(v_total_num);
			pos.setMat_cl_dsn(wgt);
			pos.setMat_cl_dsn_cnt(i);
			pos.setCl_undsn(wgt == null ? null : (-wgt));// 实物重量
			this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
		}

		if (path.contains(processpoint.smooth_code)) {
			// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
			pps.setSr_dsn(wgt);
//			pps.setSr_dsn_cnt(v_total_num);
			pps.setMat_sr_dsn(wgt);
			pps.setMat_sr_dsn_cnt(i);
			pps.setSr_undsn(wgt == null ? null : (-wgt.doubleValue()));// 实物重量
//			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(order_no);
			pos.setSr_dsn(wgt);
//			pos.setSr_dsn_cnt(v_total_num);
			pos.setMat_sr_dsn(wgt);
			pos.setMat_sr_dsn_cnt(i);
			pos.setSr_undsn(wgt == null ? null : (-wgt));// 实物重量
			this.getMapper(PlnOrderStatisticMapper.class).doUpdateSrPlaned(pos);
		}
		if (path.contains(processpoint.rolling_code)) {
			// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
			pps.setRl_dsn(wgt);
//			pps.setSr_dsn_cnt(v_total_num);
			pps.setMat_rl_dsn(wgt);
			pps.setMat_rl_dsn_cnt(i);
			pps.setRl_undsn(wgt == null ? null : (-wgt.doubleValue()));// 实物重量
//			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(order_no);
			pos.setRl_dsn(wgt);
//			pos.setSr_dsn_cnt(v_total_num);
			pos.setMat_rl_dsn(wgt);
			pos.setMat_rl_dsn_cnt(i);
			pos.setRl_undsn(wgt == null ? null : (-wgt));// 实物重量
			this.getMapper(PlnOrderStatisticMapper.class).doUpdateRlPlaned(pos);
		}
		if (path.contains(processpoint.pickle_code)) {
			// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
			pps.setPc_dsn(wgt);
//			pps.setSr_dsn_cnt(v_total_num);
			pps.setMat_pc_dsn(wgt);
			pps.setMat_pc_dsn_cnt(i);
			pps.setPc_undsn(wgt == null ? null : (-wgt.doubleValue()));// 实物重量
//			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(order_no);
			pos.setPc_dsn(wgt);
//			pos.setSr_dsn_cnt(v_total_num);
			pos.setMat_pc_dsn(wgt);
			pos.setMat_pc_dsn_cnt(i);
			pos.setPc_undsn(wgt == null ? null : (-wgt));// 实物重量
			this.getMapper(PlnOrderStatisticMapper.class).doUpdatePcPlaned(pos);
		}
		this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
	}

	public void updatePlnStatic(String prod_order_no, String order_no, String process_code, Double single_wgt,
			boolean flag) {

		Double wgt = -single_wgt;
		if (flag) {
			wgt = single_wgt;
		}

		List<ComBaseInfo> info = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(info);
		// 获取虚拟母卷的下一工序代码，计算下一工序的 已设计量/数，欠设计量：欠设计量 +=(母卷单重 )
		if (Utils.isNotEmpty(process_code)) {
			if (processpoint.cross_cutting_code.equals(process_code)) {
				// 修改生产订单进程表
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(prod_order_no);
				pps.setCl_undsn(wgt);
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
				// 修改订单进程表
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(order_no);
				pos.setCl_undsn(wgt);
				this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
			} else if (processpoint.slitting_code.equals(process_code)) {
				// 修改生产订单进程表
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(prod_order_no);
				pps.setLw_undsn(wgt);
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
				// 修改订单进程表
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(order_no);
				pos.setLw_undsn(wgt);
				this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
			} else if (processpoint.anneal_code.equals(process_code)) {
				// 修改生产订单进程表
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(prod_order_no);
				pps.setAn_undsn(wgt);
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
				// 修改订单进程表
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(order_no);
				pos.setAn_undsn(wgt);
				this.getMapper(PlnOrderStatisticMapper.class).doUpdateAnPlaned(pos);
			} else if (processpoint.smooth_code.equals(process_code)) {
				// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(prod_order_no);
				pps.setSr_undsn(wgt); // 实物重量
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

				// 修改订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(order_no);
				pos.setSr_undsn(wgt);// 实物重量
				this.getMapper(PlnOrderStatisticMapper.class).doUpdateSrPlaned(pos);
			} else if (processpoint.rolling_code.equals(process_code)) {
				// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(prod_order_no);
				pps.setRl_undsn(wgt); // 实物重量
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

				// 修改订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(order_no);
				pos.setRl_undsn(wgt);// 实物重量
				this.getMapper(PlnOrderStatisticMapper.class).doUpdateRlPlaned(pos);
			} else if (processpoint.pickle_code.equals(process_code)) {
				// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(prod_order_no);
				pps.setPc_undsn(wgt); // 实物重量
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

				// 修改订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(order_no);
				pos.setPc_undsn(wgt);// 实物重量
				this.getMapper(PlnOrderStatisticMapper.class).doUpdatePcPlaned(pos);
			}
		}
	}

	/**
	 * 子卷置为无效
	 * 
	 * @param child 子卷
	 */
	public void deleteChild(List<PlnMaterielDetail> child) {
		for (PlnMaterielDetail pln : child) {
			List<PlnMaterielDetail> child_c = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + pln.getObject_no_vt()
							+ "' and nvl(invalid_flg,0) =0 and object_no is null",
					"", 0, 0);
			if (Utils.isNotEmpty(child_c)) {
				deleteChild(child_c);
			}
			// 将子卷置为无效
			this.getMapper(PlnMaterielDetailMapper.class).ChildToInvalid(pln);
		}
	}

	public void recoveryChild(List<PlnMaterielDetail> child) {
		for (PlnMaterielDetail pln : child) {
			List<PlnMaterielDetail> child_c = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + pln.getObject_no_vt() + "' and invalid_flg = '1'", "", 0, 0);
			if (Utils.isNotEmpty(child_c)) {
				recoveryChild(child_c);
			}
			// 将子卷置为有效
			this.getMapper(PlnMaterielDetailMapper.class).ChildToValid(pln);
		}
	}

	/**
	 * 删除虚拟子卷
	 * 
	 * @param child
	 * @throws Exception
	 */
	public void deleteChildTrue(List<PlnMaterielDetail> child) throws Exception {
		for (PlnMaterielDetail pln : child) {
			// 是否挂单
			if (Utils.isNotEmpty(pln.getObject_no())) {
				throw new Exception("虚拟子卷[" + pln.getObject_no_vt() + "]作为后一工序的原料，已经挂单，无法释放！");
			}
			// 是否有子卷
			List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + pln.getObject_no_vt() + "' and nvl(invalid_flg,0) = '0'", null, 0, 0);
			if (Utils.isNotEmpty(pmd)) {
				deleteChildTrue(pmd);
			}

		}
	}

	/**
	 * 判断下一个工序是否做了计划
	 * 
	 * @param pmd
	 * @throws Exception
	 */
	public void JudgeIsOrNotPlan(PlnMaterielDetail pmd) throws Exception {

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);

		if (processpoint.slitting_code.equals(pmd.getNext_dsn_process_code())
				&& Utils.isNotEmpty(pmd.getLw_plan_no())) {
			throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做分条计划，无法删除！");
		} else if (processpoint.cross_cutting_code.equals(pmd.getNext_dsn_process_code())
				&& Utils.isNotEmpty(pmd.getCl_plan_no())) {
			throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做开平计划，无法删除！");
		} else if (processpoint.anneal_code.equals(pmd.getNext_dsn_process_code())
				&& Utils.isNotEmpty(pmd.getAn_plan_no())) {
			throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做罩退计划，无法删除！");
		} else if (processpoint.smooth_code.equals(pmd.getNext_dsn_process_code())
				&& Utils.isNotEmpty(pmd.getSr_plan_no())) {
			throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做平整计划，无法删除！");
		} else if (processpoint.rolling_code.equals(pmd.getNext_dsn_process_code())
				&& Utils.isNotEmpty(pmd.getRl_plan_no())) {
			throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做轧制计划，无法删除！");
			// TODO
		} else if (Utils.isNotEmpty(pmd.getRl_plan_no())) {
			throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做酸洗计划，无法删除！");
		}
	}

	/**
	 * 获取当前工序的下下一个有效工序
	 * 
	 * @param code         当前工序代码 1 分条/2 开平/3 罩退/4 平整/5 轧制/6 酸洗
	 * @param object_no_vt 虚拟母物料号
	 * @return 如果下下一个工序不存在 则返回 ""
	 * @throws Exception
	 */
	public String getNextProcessCode(String code, String object_no_vt) throws Exception {

		String NextProcess = "", temp = "";
		String[] path = null;
		ArrayList<String> validpath = new ArrayList<>();
		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		if (Utils.isEmpty(code)) {
			throw new Exception("请传入当前工序代码![ 1 分条/ 2 开平/ 3 罩退/ 4 平整/ 5 轧制/ 6 酸洗]");
		}
		switch (code) {
		case "1":
			temp = processpoint.slitting_code;
			break;
		case "2":
			temp = processpoint.cross_cutting_code;
			break;
		case "3":
			temp = processpoint.anneal_code;
			break;
		case "4":
			temp = processpoint.smooth_code;
			break;
		case "5":
			temp = processpoint.rolling_code;
			break;
		case "6":
			temp = processpoint.pickle_code;
			break;
		default:
			break;
		}
		// 查询虚拟物料信息
		List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				" object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,0) = '0'", null, 0, 1);
		if (Utils.isEmpty(pmd)) {
			throw new Exception("虚拟物料[" + object_no_vt + "]信息不存在!");
		}
		// 不能再拿虚拟物料表中生产订单号去查：而应该改为库存表中的生产订单号去查；20221111 刘侣 start:
		List<YdmProductDetail> ypdL = this.getMapper(YdmProductDetailMapper.class).findWithCondition(null, " object_no_vt = '" + object_no_vt + "'", null, 0, 1);
		
		// end;
		
		// 查询生产订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				" prod_order_no = '" + ypdL.get(0).getProdorderno() + "'", null, 0, 1);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("虚拟物料[" + object_no_vt + "]对应的生产订单[" + ypdL.get(0).getProdorderno() + "]信息不存在!");
		}
		// 获取有效的工艺路径
		if (pmd.get(0).getProc_repeat_index() == null) {
			return "";
		}
		temp = getPath(ppo.get(0).getWhole_process_codes(), temp, pmd.get(0).getProc_repeat_index());
		path = temp.split("-");
		validpath = getProcessPath(path);
		if (Utils.isNotEmpty(validpath)) {
			NextProcess = validpath.get(0);
		}
		return NextProcess;
	}

	/**
	 * 判断物料是否在库
	 * 
	 * @param object_no
	 * @throws Exception
	 */
	public void JudgeIsOrNotZk(String object_no) throws Exception {
		YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).findById(object_no);
		if (Utils.isEmpty(ypd) || !"0".equals(ypd.getState())) {
			throw new Exception("物料：" + object_no + "，当前不是“在库”状态！请先入库!");
		}
	}

	/**
	 * 获取有效工序集合
	 * 
	 * @param str
	 * @return
	 */
	public ArrayList<String> getProcessPath(String[] str) {
		ArrayList<String> result = new ArrayList<String>();

		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);

		for (String temp : str) {
			if (processpoint.anneal_code.equals(temp)) {
				result.add(temp);
				continue;
			} else if (processpoint.smooth_code.equals(temp)) {
				result.add(temp);
				continue;
			} else if (processpoint.slitting_code.equals(temp)) {
				result.add(temp);
				continue;
			} else if (processpoint.cross_cutting_code.equals(temp)) {
				result.add(temp);
				continue;
			} else if (processpoint.rolling_code.equals(temp)) {
				result.add(temp);
				continue;
			} else if (processpoint.pickle_code.equals(temp)) {
				result.add(temp);
				continue;
			}
		}
		return result;
	}

	/**
	 * 生成原料物料附加信息
	 * 
	 * @param ppo            生产订单信息
	 * @param pmd            虚拟物料信息
	 * @param actual_process 当前工序点 交工的时候在记录实绩作业路径
	 * @throws Exception
	 * 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public void addMaterielExinfo(PlnProdorder ppo, PlnMaterielDetail pmd, String actual_process) throws Exception {
		if (Utils.isEmpty(ppo) || Utils.isEmpty(pmd)) {
			throw new Exception("请传入生产订单号和物料号[生成物料附加信息]");
		}
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		String[] path = null;
		String path_name = null, temp = null;
		boolean flag = false;
		long position = 0;
		ArrayList<String> validpath = new ArrayList<String>();
		// 获取有效工艺路径
		path = ppo.getWhole_process_codes().split("-");
		validpath = getProcessPath(path);
		PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class).findById(pmd.getObject_no());
		List<PlnMaterielDetail> pmdd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + pmd.getObject_no_vt() + "' and nvl(invalid_flg,0) = '0' ", null, 0, 1);
		if (Utils.isEmpty(pme)) {
			pme = new PrcMaterielExtinfo();
			flag = true;
		}
		if (Utils.isNotEmpty(validpath)) {
			path_name = getpath_name(validpath);
		}
		temp = StringUtils.join(validpath, "-");
		try {
			StringBuffer sb = new StringBuffer();
			for (String str : validpath) {
				sb.append(str);

			}
			position = getPosition(sb.toString(), actual_process, pmdd.get(0).getProc_repeat_index());
			pme.setObject_no(pmd.getObject_no());
			pme.setObject_no_vt(pmd.getObject_no_vt());
			pme.setWhole_process_codes(ppo.getWhole_process_codes());
			pme.setWhole_process_names(ppo.getWhole_process_names()); // 生产订单接收
			pme.setPosition(position);
			pme.setTask_process_codes(temp);
			pme.setTask_process_names(path_name);
			pme.setProd_order_no(ppo.getProd_order_no());
			pme.setOrder_no(ppo.getOrder_no());
			// 脱单之后再挂实际作业路径保留
//			if (pme.getActual_process() == null) {
//				pme.setActual_process(actual_process);
//			} else {
//				pme.setActual_process(pme.getActual_process() + "-" + actual_process);
//			}
			pme.setCreate_man(userName);
			pme.setCreate_time(new Date());
			if (!flag) {
				this.getMapper(PrcMaterielExtinfoMapper.class).update(pme);
			} else {
				this.getMapper(PrcMaterielExtinfoMapper.class).insert(pme);
			}
		} catch (Exception ex) {
			throw new Exception(ex.getStackTrace() + "生成物料附加信息失败!");
		}
	}

	/**
	 * 交工生成子卷物料附加信息
	 * 
	 * @param object_no
	 * @param sub_object_no
	 * @param actual_process
	 * @param object_no_vt
	 * @throws Exception 子卷根据母卷的作业路径继续往下走
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public void addChildMaterielExinfo(String object_no, String sub_object_no, String object_no_vt,
			String actual_process) throws Exception {
		boolean flag = false;
		// 查询母卷物料附加信息
		PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class).findById(object_no);
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if (pme != null) {
			// 子卷物料附加信息
			PrcMaterielExtinfo child = this.getMapper(PrcMaterielExtinfoMapper.class).findById(sub_object_no);
			if (Utils.isEmpty(child)) {
				child = new PrcMaterielExtinfo();
				flag = true;
			}
			BeanUtils.copyProperties(pme, child);
			try {
				child.setObject_no(sub_object_no);
				child.setObject_no_vt(object_no_vt);
				pme.setCreate_man(userName);
				pme.setCreate_time(new Date());
				if (child.getActual_process() == null) {
					child.setActual_process(actual_process);
				} else {
					child.setActual_process(child.getActual_process() + "-" + actual_process);
				}
				if (!flag) {
					child.setPosition((child.getPosition() == null ? 0 : child.getPosition()) + 1);
					this.getMapper(PrcMaterielExtinfoMapper.class).update(child);
				} else {
					child.setPosition((pme.getPosition() == null ? 0 : pme.getPosition()) + 1);
					this.getMapper(PrcMaterielExtinfoMapper.class).insert(child);
				}
			} catch (Exception e) {
				throw new Exception("生成物料附加信息失败!");
			}
		}
	}

	/**
	 * 交工修改母卷实际作业路径
	 * 
	 * @param object_no
	 * @param actual_process
	 * @param flag           true 交工 false 撤销
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public void updateMExInfo(String object_no, String actual_process, boolean flag) {
		// 查询母卷物料附加信息
		PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class).findById(object_no);
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if (Utils.isNotEmpty(pme)) {
			if (flag) {
				// 母卷记录实际作业路径
				if (pme.getActual_process() == null) {
					pme.setActual_process(actual_process);
				} else {
					pme.setActual_process(pme.getActual_process() + "-" + actual_process);
				}
				pme.setPosition((pme.getPosition() == null ? 0 : pme.getPosition()));
			} else {
				if (Utils.isNotEmpty(pme.getActual_process())) {
					String[] result = pme.getActual_process().split("-");
					if (Utils.isNotEmpty(result)) {
						if (result.length > 1) {
							pme.setActual_process(StringUtils.substringBeforeLast(pme.getActual_process(),
									"-" + result[result.length - 1]));
						} else {
							pme.setActual_process("");
						}
					}
				}
				pme.setPosition(pme.getPosition());
			}
			pme.setCreate_man(userName);
			pme.setCreate_time(new Date());
			this.getMapper(PrcMaterielExtinfoMapper.class).update(pme);
		}
	}

	/**
	 * 脱单清空物料附加信息
	 * 
	 * @param object_no
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public void updateMaterielExinfo(String object_no) {
		PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class).findById(object_no);
		if (pme != null) {
			pme.setObject_no(object_no);
			pme.setObject_no_vt("");
			pme.setTask_process_codes("");
			pme.setTask_process_names("");
			pme.setWhole_process_codes("");
			pme.setWhole_process_names("");
			pme.setProd_order_no("");
			pme.setOrder_no("");
			pme.setPosition(pme.getPosition()); // 脱单的时候位置回退一格
			// 实际作业路径不变
//			if (Utils.isNotEmpty(pme.getActual_process())) {
//				String [] result = pme.getActual_process().split("-");
//				if (Utils.isNotEmpty(result)) {
//					if (result.length>1) {
//						pme.setActual_process(StringUtils.substringBeforeLast(pme.getActual_process(), "-"+result[result.length-1])); 
//					}else {
//						pme.setActual_process("");
//					}
//				}
//			}
			this.getMapper(PrcMaterielExtinfoMapper.class).update(pme);
		}
	}

	/**
	 * 获取工艺路径名称
	 * 
	 * @param validpath
	 * @return
	 * @throws Exception
	 */
	public String getpath_name(ArrayList<String> validpath) throws Exception {
		String path_name = null;
		List<String> temp = new ArrayList<String>();
		if (validpath.size() == 0) {
			path_name = this
					.getMapper(ComBaseProcessRStationMapper.class).findWithCondition(null,
							"process_code = '" + validpath.get(0) + "' and validflag = '1'", null, 0, 1)
					.get(0).getProcess_desc();
		} else {
			for (String str : validpath) {
				List<ComBaseProcessRStation> com = this.getMapper(ComBaseProcessRStationMapper.class)
						.findWithCondition(null, "process_code = '" + str + "' and validflag = '1'", null, 0, 1);
				temp.add(com.get(0).getProcess_desc());
			}
			path_name = StringUtils.join(temp, "-");
		}
		return path_name;
	}
	
	/**
	 * 循环获取一个卷虚拟物料内所有条数据
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel queryAllpmd(String object_no) throws Exception {
		ResultModel rm = new ResultModel("200", null);
		
		List<PlnMaterielDetail> allpmd = new ArrayList<>();
		List<PlnMaterielDetail> lpmd = new ArrayList<>();
		// 查询当前第一条数据：
		lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no = '" + object_no + "'", "", 0, 1);
		if (lpmd.size() > 0) {
			allpmd.add(lpmd.get(0));
			for (int i = 0; i < 20; i++) {
				// 将上一条的object_no_vt作为查询下一条的 mat_object_no_vt:
				lpmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '" + lpmd.get(0).getObject_no_vt() + "'", "", 0, 1);
				if (lpmd.size() == 0) {
					// 如果没有下一条数据，跳出：
					break;
				}
				allpmd.add(lpmd.get(0));
			}
			if (allpmd.size() < 2) {
				rm.setState("500");
				rm.setMsgInfo("该卷总工序少于2个，请联系管理员");
			} else {
				// 先注释掉：20230130刘侣
				// 再次判断是否倒数第二条数据的next_process_code 为平整 C：
//				if (!"C".equals(allpmd.get(allpmd.size() - 2).getNext_process_code())) {
//					rm.setState("500");
//					rm.setMsgInfo("该卷虚拟物料信息的最后一道工序不是平整，请联系管理员");
//				} else {
//					rm.setData(allpmd);
//				}
				// end
				rm.setData(allpmd);
			}
		} else {
			rm.setState("500");
			rm.setMsgInfo("未查询到该卷的虚拟物料信息");
		}
		
		// 返回所有查询的数据：
		return rm;
	}

	/**
	 * 更改作业路径
	 * 
	 * @param object_no    物料号
	 * @param task_process 作业路径
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel updateTask_process(String object_no, String task_process) throws Exception {
		ResultModel rm = new ResultModel("200", null);
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); //操作时间
		String username=(String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if (Utils.isEmpty(object_no) || Utils.isEmpty(task_process)) {
			rm.setState("500");
			rm.setMsgInfo("请传入正确的参数!");
			return rm;
		}

		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);

		// 查询虚拟物料表【PLN_MATERIEL_DETAIL】---- where NVL(INVALID_FLG,0)=0 AND OBJECT_NO =
		// 实物卷号
		List<PlnMaterielDetail> pmdd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no = '" + object_no + "' and nvl(invalid_flg,0) = '0'", "", 0, 1);
		// 获取物料附加信息
		PrcMaterielExtinfo exinfo = this.getMapper(PrcMaterielExtinfoMapper.class).findById(object_no);
		if (Utils.isEmpty(exinfo)) {
			rm.setState("500");
			rm.setMsgInfo("未找到物料附加[" + object_no + "]信息,请刷新页面再操作!");
			return rm;
		}
		// 如果传入的作业路径与原作业路径一致
		if (exinfo.getTask_process_codes().equals(task_process)) {
			rm.setState("500");
			rm.setMsgInfo("作业路径未发现改变,请刷新后重新操作!");
			return rm;
		}
		// 防止多页面操作
		if (Utils.isEmpty(pmdd)) {
			rm.setState("500");
			rm.setMsgInfo("未找到虚拟物料[" + object_no + "]信息,请刷新页面再操作!");
			return rm;
		} else if (Utils.isNotEmpty(pmdd.get(0).getNext_process_code())) {
			if (pmdd.get(0).getNext_process_code().equals(processpoint.anneal_code)
					&& (pmdd.get(0).getReplaced_times() != null && pmdd.get(0).getReplaced_times() != 2)
					&& pmdd.get(0).getAn_plan_no() != null) {
				throw new Exception("虚拟物料[" + object_no + "]已做罩退计划，无法修改作业路径！");
			}
			if (pmdd.get(0).getNext_process_code().equals(processpoint.slitting_code)
					&& pmdd.get(0).getLw_plan_no() != null) {
				throw new Exception("虚拟物料[" + object_no + "]已做分条计划，无法修改作业路径！");
			}
			if (pmdd.get(0).getNext_process_code().equals(processpoint.smooth_code)
					&& pmdd.get(0).getSr_plan_no() != null) {
				throw new Exception("虚拟物料[" + object_no + "]已做平整计划，无法修改作业路径！");
			}
			if (pmdd.get(0).getNext_process_code().equals(processpoint.cross_cutting_code)
					&& pmdd.get(0).getCl_plan_no() != null) {
				throw new Exception("虚拟物料[" + object_no + "]已做开平计划，无法修改作业路径！");
			}
			if (pmdd.get(0).getNext_process_code().equals(processpoint.pickle_code)
					&& pmdd.get(0).getCl_plan_no() != null) {
				throw new Exception("虚拟物料[" + object_no + "]已做酸洗计划，无法修改作业路径！");
			}
			if (pmdd.get(0).getNext_process_code().equals(processpoint.rolling_code)
					&& pmdd.get(0).getCl_plan_no() != null) {
				throw new Exception("虚拟物料[" + object_no + "]已做轧制计划，无法修改作业路径！");
			}
		}
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		// 脱单的时候会清空物料附加信息所以复制一个供后面流程使用
		PrcMaterielExtinfo pme = new PrcMaterielExtinfo();
		BeanUtils.copyProperties(exinfo, pme);

		int idx = 0;
		idx += exinfo.getPosition();
		// 20220905 刘侣 start：恢复成之前的，还是注释掉吧
		// 获取订单 变更作业路径 ：防止误删除多了工序，前面工序删的时候可能会删掉后面所有子工序；
//		ChangeProcess(pmdd, task_process, idx);
		// end

		String[] Apath = task_process.split("-");
		ArrayList<String> Avalidpath = new ArrayList<String>(Arrays.asList(Apath));
		// 查询虚拟物料表【PLN_MATERIEL_DETAIL】---- where NVL(INVALID_FLG,0)=0 AND OBJECT_NO =
		// 实物卷号
		List<PlnMaterielDetail> pmddd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no = '" + object_no + "' and nvl(invalid_flg,0) = '0'", "", 0, 1);
		// 修改物料附加信息
		// 写物料充当脱单履历表[MIL_MAT_REPLACE_LOG] MilMatReplaceLog
		// 物料充当脱单履历
		List<PlnMatReplaceLog> lmmrl = this.getMapper(PlnMatReplaceLogMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long iNo = 1;
		if (lmmrl != null && lmmrl.size() > 0) {
			iNo = lmmrl.get(0).getSerial_no() + 1;
		}
		PlnMatReplaceLog mmrl = new PlnMatReplaceLog();
		BeanUtils.copyProperties(pmdd.get(0), mmrl);
		mmrl.setSerial_no(iNo++);
		// 写错了，应该历史不是 挂单(2)，否则挂单管理的可上料重量会负得很多，正常最多负1.*：20220913刘侣
		// 而从计算来看，如果置为0，那就不对了，订单量+脱单量-挂单量：80 + 59.02 - 81.07 
		// 这个动作是先脱单再挂单，所以既不能只是脱单也不能只是挂单：将其置为新type：-1 先脱单后挂单适用于修改工艺路径中的删除最后一道平整工序
		// 这个先脱单后挂单在挂单历史和脱单历史都查不到，没必要查到；
//		mmrl.setOpt_type("2");
		mmrl.setOpt_type("-1");
		
		mmrl.setCreate_man_name(userName);
		mmrl.setCreate_time(new Date());
		mmrl.setRemark("更改作业路径!");
		this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
		// 修改物料附加信息
//		pme.setObject_no_vt(pmddd.get(0).getObject_no_vt());
		pme.setTask_process_codes(task_process);
		pme.setCreate_man(userName);
		pme.setCreate_time(new Date());
		pme.setTask_process_names(getpath_name(Avalidpath));
		this.getMapper(PrcMaterielExtinfoMapper.class).update(pme);
		// 作业路径发生修改,将原设计订单脱单,根据新的作业路径重新设计
		/* if (!task_process.equals(pme.getTask_process_codes())) { */
//			CommonPage<PlnMaterielDetail> oci = new CommonPage<PlnMaterielDetail>();
//			List<PlnMaterielDetail> lpm = new ArrayList<PlnMaterielDetail>();
//			PlnMaterielDetail pmd = new PlnMaterielDetail();
//			pmd.setObject_no(object_no);
//			pmd.setObject_no_vt(pme.getObject_no_vt());
//			lpm.add(pmd);
//			oci.setObjectList(lpm);

		/*
		 * // 获取物料库存信息 YdmProductDetail ypd =
		 * this.getMapper(YdmProductDetailMapper.class).findById(object_no);
		 * 
		 * // 根据新的作业路径重新设计 // String process = task_process; String process = null; //
		 * 传入的作业路径 - 已经生产的工序 if (task_process.contains("-")) { process =
		 * StringUtils.substringAfter(task_process, pme.getActual_process() + "-"); }
		 * else { process = StringUtils.substringAfter(task_process,
		 * pme.getActual_process()); } // 删除虚拟物料信息
		 * this.getBean(PlnMaterielDetailServiceImpl.class).doCancelChild(pmdd);
		 * 
		 * // 脱单 // ResultModel tuodan =
		 * this.getBean(PlnMaterielDetailServiceImpl.class).doMaterialReplace(oci); //
		 * if (!"200".equals(tuodan.getState())) { // throw new
		 * Exception("作业路径更改失败!["+tuodan.getMsgInfo()+"]"); // } // for (int i = 1; i <
		 * pme.getPosition().intValue(); i++) { // process =
		 * StringUtils.substringAfter(task_process,"-"); // } String[] Apath =
		 * task_process.split("-"); ArrayList<String> Avalidpath = new
		 * ArrayList<String>(Arrays.asList(Apath)); // 作业路径!=已完成的工序路径 if
		 * (Utils.isNotEmpty(process)) { String[] path = process.split("-");
		 * ArrayList<String> validpath = new ArrayList<String>(Arrays.asList(path));
		 * List<DesignInfo> infos = new ArrayList<DesignInfo>();
		 * 
		 * // 调用设计信息接口 DesignInfo info = new DesignInfo(); info.setCurrentProcIndex(0);
		 * info.setObject_no(object_no); info.setProcess(validpath);
		 * info.setProd_order_no(pme.getProd_order_no());
		 * info.setSingle_wgt(ypd.getFactweight()); infos.add(info);
		 * this.getBean(MesApiDesignInfoImpl.class).Design_Plan_Info(infos, null);
		 * ResultModel design =
		 * this.getBean(MesApiDesignInfoImpl.class).Design_Plan_Info(infos, null); if
		 * (!"200".equals(design.getState())) { throw new
		 * Exception(design.getMsgInfo()); }
		 * 
		 * // 修改生产订单进程表、订单进程表 //
		 * this.getBean(MesApiDesignInfoImpl.class).updateOrderStatic(pme.
		 * getProd_order_no(), pme.getOrder_no(), validpath.toString(),
		 * ypd.getFactweight(),true);
		 * 
		 * // // 查询生产订单信息 // List<PlnProdorder> lpp =
		 * this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
		 * "prod_order_no = '"+pme.getProd_order_no()+"'", null, 0, 0); // // //
		 * //调用物流接口，关联实物和生产订单信息 // ypd.setCustomer_no(lpp.get(0).getCustomer_no()); //
		 * ypd.setCustomer_nm(lpp.get(0).getCustomer_name()); //
		 * ypd.setReceiv_nm(lpp.get(0).getReciver_unit_name()); //
		 * ypd.setReceiv_no(lpp.get(0).getReciver_unit_no()); //
		 * ypd.setProdorderno(lpp.get(0).getProd_order_no()); //
		 * ypd.setOrderno(lpp.get(0).getOrder_no()); //
		 * ypd.setObject_no_vt(pmdd.get(0).getObject_no_vt()); //
		 * this.getBean(YdmProductDetailMapper.class).doFinshedProductActUpdate(ypd);
		 * 
		 * // 查询虚拟物料表【PLN_MATERIEL_DETAIL】---- where NVL(INVALID_FLG,0)=0 AND OBJECT_NO
		 * = // 实物卷号 List<PlnMaterielDetail> pmddd =
		 * this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
		 * "object_no = '" + object_no + "' and nvl(invalid_flg,0) = '0'", "", 0, 1);
		 * 
		 * // 写物料充当脱单履历表[MIL_MAT_REPLACE_LOG] MilMatReplaceLog // 物料充当脱单履历
		 * List<PlnMatReplaceLog> lmmrl =
		 * this.getMapper(PlnMatReplaceLogMapper.class).findWithCondition(null, "",
		 * " serial_no desc ", 0, 1); long iNo = 1; if (lmmrl != null && lmmrl.size() >
		 * 0) { iNo = lmmrl.get(0).getSerial_no() + 1; } PlnMatReplaceLog mmrl = new
		 * PlnMatReplaceLog(); BeanUtils.copyProperties(pmdd.get(0), mmrl);
		 * mmrl.setSerial_no(iNo++); mmrl.setOpt_type("2");
		 * mmrl.setCreate_man_name(userName); mmrl.setCreate_time(new Date());
		 * mmrl.setRemark("更改作业路径!");
		 * this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl); // 修改物料附加信息
		 * pme.setObject_no_vt(pmddd.get(0).getObject_no_vt());
		 * pme.setTask_process_codes(task_process); // if (pme.getPosition() == null) {
		 * // pme.setPosition(1l); // } // if (Utils.isNotEmpty(validpath)) { // if
		 * (pme.getActual_process() == null) { //
		 * pme.setActual_process(validpath.get(0)); // } else { //
		 * pme.setActual_process(pme.getActual_process() + "-" + validpath.get(0)); // }
		 * // } } pme.setCreate_man(userName); pme.setCreate_time(new Date());
		 * pme.setTask_process_names(getpath_name(Avalidpath));
		 * this.getMapper(PrcMaterielExtinfoMapper.class).update(pme); }
		 */
		YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).doFind(object_no, null);
		if (ypd!=null) {
			// 待入库和入库都可以修改：20220827 刘侣
			if (!"-1".equals(ypd.getState()) && !"0".equals(ypd.getState())) {
				throw new Exception("卷号【"+object_no+"】不是待入库或者入库状态，无法更改作业路径");
			}
			// 只有当前工序是倒数第二道工序才转成品库：因为要去掉最后一道平整工序；
			ResultModel rmQuery = this.queryAllpmd(ypd.getCoilno());
			if ("500".equals(rmQuery.getState())) {
				throw new Exception("卷号【"+object_no+"】" + rmQuery.getMsgInfo());
			} else {
				// 返回数据正常，可删除最后一到为平整的工序：改为删除最后的任意一道工序
				//判断当前卷的工序是否是平整之前的倒数第二道工序：思路，如果是倒数第二道工序，那么返回的总的工序数为2条；
				List<PlnMaterielDetail> allpmd = (List<PlnMaterielDetail>) rmQuery.getData();
				String status = "5BRL03"; // 作业中
				if (allpmd.size() == 2) {
					status = "5BRL10"; // 作业完成
					if ("500202".equals(ypd.getStorageattr())) {
						ypd.setStorageattr("500203");//在制库转成品库
						this.getMapper(YdmProductDetailMapper.class).update(ypd);
						// 判断是否有入库记录：
						List<YdmProductInlist> lypi = this.getMapper(YdmProductInlistMapper.class).findWithCondition(null, "STORAGEATTR = '500202' and COILNO = '" + object_no + "'", "", 0, 1);
						if (lypi.size() != 0) {
							// 说明有入库记录：修改入库记录的仓库为成品库：
							YdmProductInlist ypi = lypi.get(0);
							ypi.setStorageattr("500203");
							this.getMapper(YdmProductInlistMapper.class).update(ypi);
						}
					}
				}
				//移除下道工序 
				this.getMapper(PlnMaterielDetailMapper.class).doReMoveNextProcess(allpmd.get(allpmd.size() - 2).getObject_no_vt(), status);
			}
			
			
		}
		
		//日志
		MesOprLog mol = new MesOprLog("生产管理", "修改作业路径", "删除最后一道工序", username, opr_time, ypd.getCoilno(), null, null, null, "原料卷号："+ypd.getMaterailcoilno());
		this.getMapper(MesOprLogMapper.class).insert(mol);
		
		rm.setMsgInfo("作业路径修改成功! ");
		return rm;
	}

	/**
	 * 订单变更申报
	 * 
	 * @param order_no 订单号
	 * @param cTypes   变更类型组合 ：“10,20” 用逗号分隔 变更类型 1B 新增退火工序； 1E 新增分条工序 1D 新增开平工序； 1C
	 *                 新增平整工序； 1A 新增轧制工序 0B 减少退火工序； 0E 减少分条工序 0D 减少开平工序； 0C 减少平整工序；
	 *                 0A 减少轧制工序 20 加工计划变更（单纯只变化分条或开平规格）
	 * @return
	 * @throws Exception
	 */
	public boolean canOrderChange(String order_no, String cTypes) throws Exception {
		boolean flag = false;
		int index = 0;
		// 工序信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);

		// 获取生产订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"order_no = '" + order_no + "'", "", 0, 0);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("未找到订单[" + order_no + "]信息!");
		}
		// 将老工艺路径，保存为 工序路径类_数组形式；
		// 获取有效工艺路径
		List<ProcessUtils> old_proc = new ArrayList<ProcessUtils>();
		String[] path = ppo.get(0).getWhole_process_codes().split("-");
		ArrayList<String> validpath = getProcessPath(path);
		if (Utils.isNotEmpty(validpath)) {
			for (String str : validpath) {
				ProcessUtils pro = new ProcessUtils();
				pro.setProc_code(str);
				pro.setProc_index(index++);
				pro.setProc_name(this.getMapper(ComBaseProcessRStationMapper.class)
						.findWithCondition(null, "process_code = '" + str + "' and validflag = '1'", null, 0, 1).get(0)
						.getProcess_desc());
				pro.setRepeat_times(0);
				pro.setStatus("0");
				old_proc.add(pro);
			}
		}
		String regex1 = "0[A-Z|a-z]"; // 匹配"0x"
		String regex2 = "1[A-Z|a-z]"; // 匹配"1x"
		boolean flag_is_o = false;
		// 倒序循环
		String[] c_arr = cTypes.split(",");
		for (int i = c_arr.length - 1; i >= 0; i--) {
			// 判断是否有工序变更？(包含 "1X"、"0X"变更类型的)，如果有，则：
			if (Pattern.matches(regex1, c_arr[i])) {
				switch (c_arr[i]) {
				// 将老工序数组中，从后往前，将状态为0的"X"工序状态标记为 减少：-1； 如果找不到“X”工序，则报错退出“找不到xx工序，无法减少！”；
				case "0B":
					for (int j = old_proc.size() - 1; j >= 0; j--) {
						if (processpoint.anneal_code.equals(old_proc.get(j).getProc_code())
								&& "0".equals(old_proc.get(j).getStatus())) {
							old_proc.get(j).setStatus("-1");
							flag = false;
							break;
						} else {
							flag = true;
						}
					}
					if (flag) {
						throw new Exception("找不到退火工序，无法减少！");
					}
					break;
				case "0E":
					for (int j = old_proc.size() - 1; j >= 0; j--) {
						if (processpoint.slitting_code.equals(old_proc.get(j).getProc_code())
								&& "0".equals(old_proc.get(j).getStatus())) {
							old_proc.get(j).setStatus("-1");
							flag = false;
							break;
						} else {
							flag = true;
						}
					}
					if (flag) {
						throw new Exception("找不到分条工序，无法减少！");
					}
					break;
				case "0D":
					for (int j = old_proc.size() - 1; j >= 0; j--) {
						if (processpoint.cross_cutting_code.equals(old_proc.get(j).getProc_code())
								&& "0".equals(old_proc.get(j).getStatus())) {
							old_proc.get(j).setStatus("-1");
							flag = false;
							break;
						} else {
							flag = true;
						}
					}
					if (flag) {
						throw new Exception("找不到开平工序，无法减少！");
					}
					break;
				case "0C":
					for (int j = old_proc.size() - 1; j >= 0; j--) {
						if (processpoint.smooth_code.equals(old_proc.get(j).getProc_code())
								&& "0".equals(old_proc.get(j).getStatus())) {
							old_proc.get(j).setStatus("-1");
							flag = false;
							break;
						} else {
							flag = true;
						}
					}
					if (flag) {
						throw new Exception("找不到平整工序，无法减少！");
					}
					break;
				case "0A":
					for (int j = old_proc.size() - 1; j >= 0; j--) {
						if (processpoint.rolling_code.equals(old_proc.get(j).getProc_code())
								&& "0".equals(old_proc.get(j).getStatus())) {
							old_proc.get(j).setStatus("-1");
							flag = false;
							break;
						} else {
							flag = true;
						}
					}
					if (flag) {
						throw new Exception("找不到轧制工序，无法减少！");
					}
					break;
				case "0P":
					for (int j = old_proc.size() - 1; j >= 0; j--) {
						if (processpoint.pickle_code.equals(old_proc.get(j).getProc_code())
								&& "0".equals(old_proc.get(j).getStatus())) {
							old_proc.get(j).setStatus("-1");
							flag = false;
							break;
						} else {
							flag = true;
						}
					}
					if (flag) {
						throw new Exception("找不到酸洗工序，无法减少！");
					}
					break;

				default:
					break;
				}
				flag_is_o = true;
			}
		}
		if (flag_is_o) {
			// 2 一般只有一条生产订单记录
			for (PlnProdorder order : ppo) {
				// 获取当前生产订单下的所有的 [第一工序虚拟卷数组]（第一工序虚拟卷：虚拟母物料为空的虚拟卷。即对应第一个工序的虚拟卷）
				List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
						"prod_order_no = '" + order.getProd_order_no()
								+ "' and nvl(invalid_flg,0) != 1 and mat_object_no_vt is null",
						"", 0, 0);
				for (PlnMaterielDetail pln : pmd) {
					List<PlnMaterielDetail> temp = new ArrayList<PlnMaterielDetail>();
					int cnt_g = validpath.indexOf(pln.getNext_dsn_process_code());
					if (cnt_g == -1) {
						throw new Exception("工艺路径不存在 ["
								+ this.getMapper(ComBaseProcessRStationMapper.class)
										.findWithCondition(null,
												"process_code = '" + pln.getNext_dsn_process_code()
														+ "' and validflag = '1'",
												null, 0, 1)
										.get(0).getProcess_desc()
								+ "]工序");
					}
					temp.add(pln);
					// 调用 canDeleteProcess（第一工序虚拟卷信息， 老工艺路径数组，0) 因为可能涉及到挂的不同的工序所以按单个处理
					CanDeleteProcess(temp, old_proc, cnt_g, false);
				}
			}
		}

		// 是否有加工计划变更
		for (int i = 0; i < c_arr.length; i++) {
			if ("20".equals(c_arr[i])) {
				// 获取当前生产订单下的所有的 [第一工序虚拟卷数组]（第一工序虚拟卷：虚拟母物料为空的虚拟卷。即对应第一个工序的虚拟卷）
				// 2 一般只有一条生产订单记录
				for (PlnProdorder pp : ppo) {
					// 获取当前生产订单下的所有的 [第一工序虚拟卷数组]（第一工序虚拟卷：虚拟母物料为空的虚拟卷。即对应第一个工序的虚拟卷）
					List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
							"prod_order_no = '" + pp.getProd_order_no()
									+ "' and nvl(invalid_flg,0) != 1 and mat_object_no_vt is null",
							"", 0, 0);
					for (PlnMaterielDetail pln : pmd) {
						List<PlnMaterielDetail> te = new ArrayList<PlnMaterielDetail>();
						int cnt_p = validpath.indexOf(pln.getNext_dsn_process_code());
						if (cnt_p == -1) {
							throw new Exception("工艺路径不存在 [" + this.getMapper(ComBaseProcessRStationMapper.class)
									.findWithCondition(null,
											"process_code = '" + pln.getNext_dsn_process_code()
													+ "' and validflag = '1'",
											null, 0, 1)
									.get(0).getProcess_point_desc() + "]工序");
						}
						te.add(pln);
						// 调用 CanChangeProcessPlan（第一工序虚拟卷信息， 老工艺路径数组，0) 因为可能涉及到挂的不同的工序所以按单个处理
						CanChangeProcessPlan(te, old_proc, cnt_p);
					}

				}
			}
		}

		// 循环各"1X"
		// 将新工序 追加到数组最后，将状态为0的"X"工序状态标记为 新增；
		for (int i = 0; i < c_arr.length; i++) {
			if (Pattern.matches(regex2, c_arr[i])) {
				ProcessUtils pu = new ProcessUtils();
				switch (c_arr[i]) {
				case "1B":
					pu.setProc_code(processpoint.anneal_code);
					pu.setProc_index(old_proc.size());
					pu.setStatus("0");
					old_proc.add(pu);
					break;
				case "1D":
					pu.setProc_code(processpoint.cross_cutting_code);
					pu.setProc_index(old_proc.size());
					pu.setStatus("0");
					old_proc.add(pu);
					break;
				case "1C":
					pu.setProc_code(processpoint.smooth_code);
					pu.setProc_index(old_proc.size());
					pu.setStatus("0");
					old_proc.add(pu);
					break;
				case "1E":
					pu.setProc_code(processpoint.slitting_code);
					pu.setProc_index(old_proc.size());
					pu.setStatus("0");
					old_proc.add(pu);
					break;

				default:
					break;
				}
			}
		}
		return true;
	}

	/**
	 * 判断能否删除工序
	 * 
	 * @param temp
	 * @param old_proc
	 * @param idx
	 * @return 根据old_proc中状态判断是否需要删除
	 * @throws Exception
	 */
	public boolean CanDeleteProcess(List<PlnMaterielDetail> temp, List<ProcessUtils> old_proc, int idx, boolean flag)
			throws Exception {
		if (old_proc.size() - 1 < idx) {
			return true;
		}
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		String process_code = "";
		for (PlnMaterielDetail pln : temp) {
			// 判断当前虚拟母物料的下一工序，是否对应 工艺路径数组[idx]，如果不是，则报错退出“第 idx+1 个工序的虚拟母卷[xxx]对应的下一工序不是
			// 工序路径数组[idx]”；
			if (!pln.getNext_process_code().equals(old_proc.get(idx).getProc_code())) {
				throw new Exception("第 " + idx + 1 + "个工序的虚拟母卷[" + pln.getObject_no_vt() + "]对应的下一工序不是["
						+ old_proc.get(idx).getProc_name() + "]");
			}
//			if (pln.getPrev_process_code() != null && pln.getNext_process_code() != null) {
//				process_code = get_Prc_Code(pln.getStatus());
//			} else {
//				process_code = pln.getPrev_process_code() == null ? pln.getNext_process_code()
//						: pln.getPrev_process_code();
//			}

			process_code = old_proc.get(idx).getProc_code();
			// 判断当前工序是否需要删除 status == -1
			if ("-1".equals(old_proc.get(idx).getStatus()) || flag) {
				if ("-1".equals(old_proc.get(idx).getStatus())) {
					flag = true;
				}
				// 判断母卷是否正在生产
				if (processpoint.slitting_code.equals(process_code)) {
					if (pln.getLw_plan_no() != null && !"".equals(pln.getLw_plan_no())) {
						PlnLengthwisePlanDetail plpd = new PlnLengthwisePlanDetail();
						plpd.setLw_plan_no(pln.getLw_plan_no());
						plpd.setObject_no_vt(pln.getObject_no_vt());
						List<PlnLengthwisePlanDetail> lplpd = this.getMapper(PlnLengthwisePlanDetailMapper.class)
								.find(plpd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BLW01".equals(lplpd.get(0).getStatus())) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许删除工序！");
							} else if ("5BLW02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！");
							}
						}
					}
				} else if (processpoint.cross_cutting_code.equals(process_code)) {

					if (pln.getCl_plan_no() != null || !"".equals(pln.getCl_plan_no())) {
						PlnCuttolengthPlanDetail plpd = new PlnCuttolengthPlanDetail();
						plpd.setCl_plan_no(pln.getCl_plan_no());
						plpd.setObject_no_vt(pln.getObject_no_vt());
						List<PlnCuttolengthPlanDetail> lplpd = this.getMapper(PlnCuttolengthPlanDetailMapper.class)
								.find(plpd, 0, 1);

						if (lplpd != null && lplpd.size() > 0) {
							if ("5BCL01".equals(lplpd.get(0).getStatus())) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许删除工序！");
							} else if ("5BCL02".compareTo(lplpd.get(0).getStatus()) >= 0) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！");
							}
						}
					}
				} else if (processpoint.anneal_code.equals(process_code)) {
					if (pln.getAn_plan_no() != null || !"".equals(pln.getAn_plan_no())) {
						PlnAnnealPlanDetail plpd = new PlnAnnealPlanDetail();
						plpd.setAn_plan_no(pln.getAn_plan_no());
						plpd.setObject_no_vt(pln.getObject_no_vt());
						List<PlnAnnealPlanDetail> lplpd = this.getMapper(PlnAnnealPlanDetailMapper.class).find(plpd, 0,
								1);

						if (lplpd != null && lplpd.size() > 0) {
							if ("5BAN01".equals(lplpd.get(0).getStatus())) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许删除工序！");
							} else if ("5BAN02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！");
							}
						}
					}
				} else if (processpoint.smooth_code.equals(process_code)) {
					if (Utils.isNotEmpty(pln.getSr_plan_no())) {
						PlnSkinrollingPlanDetail plpd = new PlnSkinrollingPlanDetail();
						plpd.setSr_plan_no(pln.getSr_plan_no());
						plpd.setObject_no_vt(pln.getObject_no_vt());
						List<PlnSkinrollingPlanDetail> lplpd = this.getMapper(PlnSkinrollingPlanDetailMapper.class)
								.find(plpd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BSR01".equals(lplpd.get(0).getStatus())) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许删除工序！");
							} else if ("5BSR02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！");
							}
						}
					}

				} else if (processpoint.rolling_code.equals(process_code)) {
					if (Utils.isNotEmpty(pln.getRl_plan_no())) {
						PlnRollingPlanDetail plpd = new PlnRollingPlanDetail();
						plpd.setRl_plan_no(pln.getRl_plan_no());
						plpd.setObject_no_vt(pln.getObject_no_vt());
						List<PlnRollingPlanDetail> lplpd = this.getMapper(PlnRollingPlanDetailMapper.class).find(plpd,
								0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BRL01".equals(lplpd.get(0).getStatus())) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许删除工序！");
							} else if ("5BRL02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！");
							}
						}
					}

				} else if (processpoint.pickle_code.equals(process_code)) {
					if (Utils.isNotEmpty(pln.getPc_plan_no())) {
						PlnPicklePlanDetail plpd = new PlnPicklePlanDetail();
						plpd.setPc_plan_no(pln.getPc_plan_no());
						plpd.setObject_no_vt(pln.getObject_no_vt());
						List<PlnPicklePlanDetail> lplpd = this.getMapper(PlnPicklePlanDetailMapper.class).find(plpd, 0,
								1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BPC01".equals(lplpd.get(0).getStatus())) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许删除工序！");
							} else if ("5BPC02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！");
							}
						}
					}
				}
			}
			List<PlnMaterielDetail> Ary_Mats = new ArrayList<PlnMaterielDetail>();
			// 获取虚拟子卷信息
			List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + pln.getObject_no_vt() + "' and nvl(invalid_flg,0) != 1", "", 0, 0);
			if (Utils.isNotEmpty(pmd)) {
				for (PlnMaterielDetail child : pmd) {
					// 如果 虚拟子卷有实物绑定 AND 工序路径类数组[idx] 状态为 -1，则 报错退出“已经有实物[母卷号xxx]进行了xxx工序的加工,
					// 不能删除工序xxx!”
					if (child.getObject_no() != null && "-1".equals(old_proc.get(idx).getStatus())) {
						throw new Exception(
								"已经有实物[母卷号" + child.getObject_no() + "]进行了" + old_proc.get(idx).getProc_name()
										+ "工序的加工, 不能删除工序" + old_proc.get(idx).getProc_name() + "!");
					}
					Ary_Mats.add(child);
				}
				// 用于判断直接挂子卷并且母卷没挂料情况
				if (Utils.isNotEmpty(Ary_Mats)) {
					CanDeleteProcess(Ary_Mats, old_proc, idx + 1, flag);
				}
			}
		}
		return true;
	}

	/**
	 * 判断能否进行加工计划变更 (虚拟母物料数组， 老工序路径数组， 指针序号 idx)
	 * 
	 * @param temp
	 * @param old_proc
	 * @param idx
	 * @return 母卷如果正在生产或者子卷已经挂单(母卷交工) 不允许更变(针对分条开平)
	 * @throws Exception
	 */
	public boolean CanChangeProcessPlan(List<PlnMaterielDetail> temp, List<ProcessUtils> old_proc, int idx)
			throws Exception {
		if (old_proc.size() - 1 < idx) {
			return true;
		}

		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		String process_code = "";
		for (PlnMaterielDetail pln : temp) {
			// 判断当前虚拟母物料的下一工序，是否对应 工艺路径数组[idx]，如果不是，则报错退出“第 idx+1 个工序的虚拟母卷[xxx]对应的下一工序不是
			// 工序路径数组[idx]”；
			if (!pln.getNext_process_code().equals(old_proc.get(idx).getProc_code())) {
				throw new Exception("第 " + idx + 1 + "个工序的虚拟母卷[" + pln.getObject_no_vt() + "]对应的下一工序不是["
						+ old_proc.get(idx).getProc_name() + "]");
			}
			if (pln.getPrev_process_code() != null && pln.getNext_process_code() != null) {
				process_code = get_Prc_Code(pln.getStatus());
			} else {
				process_code = pln.getPrev_process_code() == null ? pln.getNext_process_code()
						: pln.getPrev_process_code();
			}
			// 如果母卷正在走的工序是分条或者开平判断是否正在生产
			if (processpoint.slitting_code.equals(process_code)) {
				if (pln.getLw_plan_no() != null && !"".equals(pln.getLw_plan_no())) {
					PlnLengthwisePlanDetail plpd = new PlnLengthwisePlanDetail();
					plpd.setLw_plan_no(pln.getLw_plan_no());
					plpd.setObject_no_vt(pln.getObject_no_vt());
					List<PlnLengthwisePlanDetail> lplpd = this.getMapper(PlnLengthwisePlanDetailMapper.class).find(plpd,
							0, 1);
					if (lplpd != null && lplpd.size() > 0) {
						if ("5BLW01".equals(lplpd.get(0).getStatus())) {
							throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许变更加工计划！");
						} else if ("5BLW02".compareTo(lplpd.get(0).getStatus()) <= 0) {
							throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许变更加工计划！");
						}
					}
				}
			} else if (processpoint.cross_cutting_code.equals(process_code)) {

				if (pln.getAn_plan_no() != null || !"".equals(pln.getAn_plan_no())) {
					PlnCuttolengthPlanDetail plpd = new PlnCuttolengthPlanDetail();
					plpd.setCl_plan_no(pln.getCl_plan_no());
					plpd.setObject_no_vt(pln.getObject_no_vt());
					List<PlnCuttolengthPlanDetail> lplpd = this.getMapper(PlnCuttolengthPlanDetailMapper.class)
							.find(plpd, 0, 1);

					if (lplpd != null && lplpd.size() > 0) {
						if ("5BCL01".equals(lplpd.get(0).getStatus())) {
							throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许变更加工计划！");
						} else if ("5BCL02".compareTo(lplpd.get(0).getStatus()) >= 0) {
							throw new Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许变更加工计划！");
						}
					}
				}
			}
			/*
			 * else if (processpoint.anneal_code.equals(process_code)) { if
			 * (pln.getAn_plan_no() != null || !"".equals(pln.getAn_plan_no())) {
			 * PlnAnnealPlanDetail plpd = new PlnAnnealPlanDetail();
			 * plpd.setAn_plan_no(pln.getAn_plan_no());
			 * plpd.setObject_no_vt(pln.getObject_no_vt()); List<PlnAnnealPlanDetail> lplpd
			 * = this.getMapper(PlnAnnealPlanDetailMapper.class).find(plpd, 0, 1);
			 * 
			 * if (lplpd != null && lplpd.size() > 0) { if
			 * ("5BAN01".equals(lplpd.get(0).getStatus())) { throw new Exception("物料[" +
			 * pln.getObject_no() + "]已经编制计划，不允许变更加工计划！"); } else if
			 * ("5BAN02".compareTo(lplpd.get(0).getStatus()) <= 0) { throw new
			 * Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许变更加工计划！"); } } } } else if
			 * (processpoint.smooth_code.equals(process_code)) { if
			 * (Utils.isNotEmpty(pln.getSr_plan_no())) { PlnSkinrollingPlanDetail plpd = new
			 * PlnSkinrollingPlanDetail(); plpd.setSr_plan_no(pln.getSr_plan_no());
			 * plpd.setObject_no_vt(pln.getObject_no_vt()); List<PlnSkinrollingPlanDetail>
			 * lplpd = this.getMapper(PlnSkinrollingPlanDetailMapper.class) .find(plpd, 0,
			 * 1); if (lplpd != null && lplpd.size() > 0) { if
			 * ("5BSR01".equals(lplpd.get(0).getStatus())) { throw new Exception("物料[" +
			 * pln.getObject_no() + "]已经编制计划，不允许变更加工计划！"); } else if
			 * ("5BSR02".compareTo(lplpd.get(0).getStatus()) <= 0) { throw new
			 * Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许变更加工计划！"); } } }
			 * 
			 * } else if (processpoint.rolling_code.equals(process_code)) { if
			 * (Utils.isNotEmpty(pln.getRl_plan_no())) { PlnRollingPlanDetail plpd = new
			 * PlnRollingPlanDetail(); plpd.setRl_plan_no(pln.getRl_plan_no());
			 * plpd.setObject_no_vt(pln.getObject_no_vt()); List<PlnRollingPlanDetail> lplpd
			 * = this.getMapper(PlnRollingPlanDetailMapper.class).find(plpd, 0, 1); if
			 * (lplpd != null && lplpd.size() > 0) { if
			 * ("5BRL01".equals(lplpd.get(0).getStatus())) { throw new Exception("物料[" +
			 * pln.getObject_no() + "]已经编制计划，不允许删除工序！"); } else if
			 * ("5BRL02".compareTo(lplpd.get(0).getStatus()) <= 0) { throw new
			 * Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！"); } } }
			 * 
			 * } else if (processpoint.pickle_code.equals(process_code)) { if
			 * (Utils.isNotEmpty(pln.getPc_plan_no())) { PlnPicklePlanDetail plpd = new
			 * PlnPicklePlanDetail(); plpd.setPc_plan_no(pln.getPc_plan_no());
			 * plpd.setObject_no_vt(pln.getObject_no_vt()); List<PlnPicklePlanDetail> lplpd
			 * = this.getMapper(PlnPicklePlanDetailMapper.class).find(plpd, 0, 1); if (lplpd
			 * != null && lplpd.size() > 0) { if ("5BPC01".equals(lplpd.get(0).getStatus()))
			 * { throw new Exception("物料[" + pln.getObject_no() + "]已经编制计划，不允许删除工序！"); }
			 * else if ("5BPC02".compareTo(lplpd.get(0).getStatus()) <= 0) { throw new
			 * Exception("物料[" + pln.getObject_no() + "]已经开始生产，不允许删除工序！"); } } }
			 * 
			 * }
			 */
			List<PlnMaterielDetail> Ary_Mats = new ArrayList<PlnMaterielDetail>();
			// 获取虚拟子卷信息
			List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + pln.getObject_no_vt() + "' and nvl(invalid_flg,0) != 1", "", 0, 0);
			if (Utils.isNotEmpty(pmd)) {
				for (PlnMaterielDetail child : pmd) {
					// 如果 虚拟子卷有实物绑定 AND 工序路径类数组[idx]为“开平”或“分条”，则 报错退出“实物卷[母卷号xxx]已经进行了xxx工序的加工,
					// 不能修改加工计划!”
					if (child.getObject_no() != null
							&& (processpoint.slitting_code.equals(old_proc.get(idx).getProc_code())
									|| processpoint.cross_cutting_code.equals(old_proc.get(idx).getProc_code()))) {
						throw new Exception("已经有实物[母卷号" + child.getObject_no() + "]进行了"
								+ old_proc.get(idx).getProc_name() + "工序的加工, 不能修改加工计划!");
					}
					Ary_Mats.add(child);
				}
				if (Utils.isNotEmpty(Ary_Mats) && !"-1".equals(old_proc.get(idx).getStatus())
						&& idx + 1 > old_proc.size()) {
					CanChangeProcessPlan(Ary_Mats, old_proc, idx + 1);
				}
			}
		}
		return true;
	}

	/**
	 * 订单接收(变更之后的订单)
	 * 
	 * @param order_no
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public void OrderReceive(String order_no) throws Exception {

		// 获取生产订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"order_no = '" + order_no + "'", "", 0, 0);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("未找到生产订单信息!");
		}
		for (PlnProdorder pln : ppo) {
			// 获取订单对应的虚拟母卷信息
			List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"prod_order_no = '" + pln.getProd_order_no()
							+ "' and nvl(invalid_flg,0) != 1 and mat_object_no_vt is null",
					"", 0, 0);
			if (Utils.isNotEmpty(pmd)) {
				ChangeProcess(pmd, pln.getWhole_process_codes(), -1);
			}
		}
	}

	/**
	 * 订单变更 工艺路径
	 * 
	 * @param pmd_list 虚拟母物料数组
	 * @param process  工序路径
	 * @param idx      第一次调用传入 -1
	 * @throws Exception
	 */
	/*
	 * @Transactional(value = "tm", rollbackFor = Exception.class) public void
	 * ChangeProcess(List<PlnMaterielDetail> pmd_list, String process, int idx)
	 * throws Exception {
	 * 
	 * // 获取工艺路径集合 String[] path = process.split("-"); ArrayList<String> validpath =
	 * getProcessPath(path); for (PlnMaterielDetail pmd : pmd_list) {
	 * 
	 * // 根据虚拟母物料的 下一工序 和 工序次数，计算其 在新工序路径数组的位置idx， 如果找不到，则报错“新工艺路径不存在 xx工序” //
	 * 获取下一个工序 // String temp = this.getBean(MesApiDesignInfoImpl.class) //
	 * .getPath(lpp.get(0).getWhole_process_codes(),
	 * processpoint.cross_cutting_code, pmdpp.get(0).getProc_repeat_index()); //
	 * TODO 获取工序 以及 index if (idx == -1) { if
	 * (Utils.isNotEmpty(pmd.getProc_repeat_index()) && pmd.getProc_repeat_index() >
	 * 1) { idx = validpath.lastIndexOf(pmd.getNext_process_code()); } else { idx =
	 * validpath.indexOf(pmd.getNext_process_code()); } if (idx == -1) { throw new
	 * Exception( "工艺路径不存在 [" + this.getMapper(ComBaseProcessRStationMapper.class)
	 * .findWithCondition(null, "process_code = '" + pmd.getNext_process_code() +
	 * "' and validflag = '1'", null, 0, 1) .get(0).getProcess_point_desc() +
	 * "]工序"); } }
	 * 
	 * // 获取虚拟子卷信息 List<PlnMaterielDetail> child =
	 * this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
	 * "mat_object_no_vt = '" + pmd.getObject_no_vt() +
	 * "' and nvl(invalid_flg,0) != 1 ", "", 0, 0); if (Utils.isNotEmpty(child)) {
	 * boolean flag_cf = false; for (PlnMaterielDetail str_c : child) { if
	 * (Utils.isNotEmpty(str_c.getObject_no())) { // 如果已完成工序包含工序路径视为已完成不参与变更。
	 * PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class)
	 * .findById(str_c.getObject_no()); // 未完成生产 if (Utils.isEmpty(pme) ||
	 * !pme.getActual_process().equals(validpath.toString())) { flag_cf = true;
	 * continue; } // 未挂单 } else { flag_cf = true; continue; } } if (!flag_cf) {
	 * continue; } } // 如果虚拟母物料的OBJECT_NO is null，则删除其对应的所有虚拟子卷信息，以及当前虚拟母物料信息；
	 * continue; if (pmd.getObject_no() == null) { if (Utils.isEmpty(child)) { //
	 * 删除母卷 this.getMapper(PlnMaterielDetailMapper.class).doDeleteId(pmd); } else {
	 * // 删除母卷以及子卷 List<PlnMaterielDetail> pmdd = new
	 * ArrayList<PlnMaterielDetail>(); pmdd.add(pmd);
	 * this.getBean(PlnMaterielDetailServiceImpl.class).doCancelChild(pmdd); }
	 * continue; // 如果母卷不为空 } else { List<PlnMaterielDetail> Ary_Mats_Matched = new
	 * ArrayList<PlnMaterielDetail>(); List<PlnMaterielDetail> Ary_Mats_Null = new
	 * ArrayList<PlnMaterielDetail>(); // 循环当前虚拟母卷 的 虚拟子物料: for (PlnMaterielDetail
	 * str : child) { // 如果 虚拟子卷无实物绑定 ，则 Ary_Mats_Null.add{虚拟子物料} if
	 * (str.getObject_no() == null) { Ary_Mats_Null.add(str); } else if
	 * (!validpath.get(idx).equals(pmd.getNext_process_code())) { throw new
	 * Exception("报错退出“实物[母卷:" + pmd.getObject_no_vt() + "]进行了[" +
	 * this.getMapper(ComBaseProcessRStationMapper.class) .findWithCondition(null,
	 * "process_code = '" + pmd.getNext_process_code() + "' and validflag = '1'",
	 * null, 0, 1) .get(0).getProcess_point_desc() + "] 工序的加工, 不能匹配新工艺路径，计划工序为：[" +
	 * this.getMapper(ComBaseProcessRStationMapper.class).findWithCondition(null,
	 * "process_code = '" + validpath.get(idx) + "' and validflag = '1'", null, 0,
	 * 1) .get(0).getProcess_point_desc() + "]!”"); } else if
	 * (validpath.get(idx).equals(pmd.getNext_process_code())) {
	 * Ary_Mats_Matched.add(str); } } if (Utils.isNotEmpty(Ary_Mats_Null)) { int
	 * nul_eq = idx + 1; // 修改作业路径,直接删除后面工序 if (nul_eq >= validpath.size()) { for
	 * (PlnMaterielDetail amn : Ary_Mats_Null) { List<PlnMaterielDetail> child_k =
	 * this.getMapper(PlnMaterielDetailMapper.class) .findWithCondition(null,
	 * "mat_object_no_vt = '" + amn.getObject_no_vt() +
	 * "' and nvl(invalid_flg,0) != 1 ", "", 0, 0); if (Utils.isEmpty(child_k)) { //
	 * 删除母卷 this.getMapper(PlnMaterielDetailMapper.class).doDeleteId(amn); } else {
	 * // 删除母卷以及子卷 List<PlnMaterielDetail> pmdd = new
	 * ArrayList<PlnMaterielDetail>(); pmdd.add(amn);
	 * this.getBean(PlnMaterielDetailServiceImpl.class).doCancelChild(pmdd); } //
	 * 修改母卷修改库存信息 // 修改母卷设计号以及下一个设计工序 // 将虚拟母卷的 下道工序清空 if
	 * (Utils.isNotEmpty(pmd.getNext_dsn_process_code())) {
	 * pmd.setNext_dsn_process_code(""); pmd.setNext_process_code("");
	 * this.getMapper(PlnMaterielDetailMapper.class).update(pmd); } // TODO
	 * 修改库存状态成品库至在制成品库 YdmProductDetail ypd =
	 * this.getMapper(YdmProductDetailMapper.class) .findById(pmd.getObject_no());
	 * if ("500202".equals(ypd.getStorageattr())) { // ypd.setStorageattr("500203");
	 * CommonPage<YdmProductDetail> cp = new CommonPage<YdmProductDetail>();
	 * List<YdmProductDetail> ydm = new ArrayList<YdmProductDetail>(); ydm.add(ypd);
	 * cp.setObjectList(ydm); cp.setMemo1("500203");
	 * this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(cp); } }
	 * continue; } ChangeProcess(Ary_Mats_Null, process, nul_eq); } if
	 * (Utils.isNotEmpty(Ary_Mats_Matched)) { int mth_eq = idx + 1; if (mth_eq >=
	 * validpath.size()) { continue; } ChangeProcess(Ary_Mats_Matched, process,
	 * mth_eq); for (PlnMaterielDetail match : Ary_Mats_Matched) { // 如果 obj_vt 无任何
	 * 虚拟子物料，则根据工艺路径，新建后续虚拟物料信息： Design_Plan_Info（生产订单号，新工序路径数组,idx，obj_vt，单重）
	 * List<PlnMaterielDetail> child_m =
	 * this.getMapper(PlnMaterielDetailMapper.class) .findWithCondition(null,
	 * "mat_object_no_vt = '" + match.getObject_no_vt() +
	 * "' and nvl(invalid_flg,0) != 1 ", "", 0, 0); if (Utils.isEmpty(child_m)) { //
	 * 删除工艺路径 if (idx + 1 > validpath.size()) { // 修改母卷设计号以及下一个设计工序 // 将虚拟母卷的 下道工序清空
	 * pmd.setNext_dsn_process_code(""); pmd.setNext_process_code("");
	 * this.getMapper(PlnMaterielDetailMapper.class).update(pmd); // 修改库存状态成品库至在制成品库
	 * YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class)
	 * .findById(match.getObject_no()); if ("500202".equals(ypd.getStorageattr())) {
	 * // ypd.setStorageattr("500203"); CommonPage<YdmProductDetail> cp = new
	 * CommonPage<YdmProductDetail>(); List<YdmProductDetail> ydm = new
	 * ArrayList<YdmProductDetail>(); ydm.add(ypd); cp.setObjectList(ydm);
	 * cp.setMemo1("500203");
	 * this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(cp); } } else {
	 * // 修改库存状态(如果物料在成品库修改到在制成品库) YdmProductDetail ypd =
	 * this.getMapper(YdmProductDetailMapper.class) .findById(match.getObject_no());
	 * if ("500203".equals(ypd.getStorageattr())) { // ypd.setStorageattr("500202");
	 * CommonPage<YdmProductDetail> cp = new CommonPage<YdmProductDetail>();
	 * List<YdmProductDetail> ydm = new ArrayList<YdmProductDetail>(); ydm.add(ypd);
	 * cp.setObjectList(ydm); cp.setMemo1("500202");
	 * this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(cp); } //
	 * 调用设计信息接口 List<DesignInfo> infos = new ArrayList<DesignInfo>(); DesignInfo
	 * info = new DesignInfo(); info.setCurrentProcIndex(idx + 1);
	 * info.setObject_no(match.getObject_no());
	 * info.setObject_no_vt(match.getObject_no_vt()); info.setProcess(validpath);
	 * info.setProd_order_no(match.getProd_order_no());
	 * info.setSingle_wgt(pmd.getSingle_weight()); infos.add(info); ResultModel
	 * result = Design_Plan_Info(infos, null); if ("500".equals(result.getState()))
	 * { throw new Exception(result.getMsgInfo()); } } } } } // 如果无子卷直接进入↓ else { //
	 * 删除工艺路径 if (idx + 1 > validpath.size()) { // 修改母卷设计号以及下一个设计工序 // 将虚拟母卷的 下道工序清空
	 * pmd.setNext_dsn_process_code(""); pmd.setNext_process_code("");
	 * this.getMapper(PlnMaterielDetailMapper.class).update(pmd); // 修改库存状态在制成品库至成品库
	 * YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class)
	 * .findById(pmd.getObject_no()); if ("500202".equals(ypd.getStorageattr())) {
	 * // ypd.setStorageattr("500203"); CommonPage<YdmProductDetail> cp = new
	 * CommonPage<YdmProductDetail>(); List<YdmProductDetail> ydm = new
	 * ArrayList<YdmProductDetail>(); ydm.add(ypd); cp.setObjectList(ydm);
	 * cp.setMemo1("500203");
	 * this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(cp); } } else {
	 * // 修改库存状态(如果物料在成品库修改到在制成品库) YdmProductDetail ypd =
	 * this.getMapper(YdmProductDetailMapper.class) .findById(pmd.getObject_no());
	 * if ("500203".equals(ypd.getStorageattr())) { // ypd.setStorageattr("500202");
	 * CommonPage<YdmProductDetail> cp = new CommonPage<YdmProductDetail>();
	 * List<YdmProductDetail> ydm = new ArrayList<YdmProductDetail>(); ydm.add(ypd);
	 * cp.setObjectList(ydm); cp.setMemo1("500202");
	 * this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(cp); } //
	 * 则根据工艺路径，新建后续虚拟物料信息： Design_Plan_Info（生产订单号，新工序路径数组, idx，当前虚拟母卷，单重） //
	 * 调用设计信息接口 List<DesignInfo> infos = new ArrayList<DesignInfo>(); DesignInfo
	 * info = new DesignInfo(); info.setCurrentProcIndex(idx);
	 * info.setObject_no(pmd.getObject_no()); info.setProcess(validpath);
	 * info.setObject_no_vt(pmd.getObject_no_vt());
	 * info.setProd_order_no(pmd.getProd_order_no());
	 * info.setSingle_wgt(pmd.getSingle_weight()); infos.add(info); ResultModel
	 * result = Design_Plan_Info(infos, null); if ("500".equals(result.getState()))
	 * { throw new Exception(result.getMsgInfo()); } } } } } }
	 */

	/**
	 * 订单变更 工艺路径
	 * 
	 * @param pmd_list 虚拟母物料数组
	 * @param process  工序路径
	 * @param idx      第一次调用传入 -1
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public void ChangeProcess(List<PlnMaterielDetail> pmd_list, String process, int idx) throws Exception {

		// 获取工艺路径集合
		String[] path = process.split("-");
		ArrayList<String> validpath = getProcessPath(path);
		StringBuffer sb = new StringBuffer();
		for (String str : validpath) {
			sb.append(str);

		}
		for (PlnMaterielDetail pmd : pmd_list) {

			// 根据虚拟母物料的 下一工序 和 工序次数，计算其 在新工序路径数组的位置idx， 如果找不到，则报错“新工艺路径不存在 xx工序”
			if (idx == -1) {
				idx = getPosition(sb.toString(), pmd.getNext_process_code(), pmd.getProc_repeat_index());
				if (idx == -1) {
					throw new Exception(
							"工艺路径不存在 ["
									+ this.getMapper(ComBaseProcessRStationMapper.class)
											.findWithCondition(null,
													"process_code = '" + pmd.getNext_process_code()
															+ "' and validflag = '1'",
													null, 0, 1)
											.get(0).getProcess_point_desc()
									+ "]工序");
				}
			}

			// 获取虚拟子卷信息
			List<PlnMaterielDetail> child = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + pmd.getObject_no_vt() + "' and nvl(invalid_flg,0) != 1 ", "", 0, 0);

			// 判断加入虚拟子卷信息都已经生产完成那么不参与变更直接跳过
			if (Utils.isNotEmpty(child)) {
				boolean flag_cf = false;
				for (PlnMaterielDetail str_c : child) {
					if (Utils.isNotEmpty(str_c.getObject_no())) {
						// 如果已完成工序包含工序路径视为已完成不参与变更。
						PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class)
								.findById(str_c.getObject_no());
						// 未完成生产
						if (Utils.isEmpty(pme) || !pme.getActual_process().equals(validpath.toString())) {
							flag_cf = true;
							continue;
						}
						// 未挂单
					} else {
						flag_cf = true;
						continue;
					}
				}
				if (!flag_cf) {
					continue;
				}
			}

			// 删除未挂单的虚拟物料信息
			List<PlnMaterielDetail> pmdd = new ArrayList<PlnMaterielDetail>();
			pmdd.add(pmd);
			deletePath(pmdd, validpath, idx);

			// 生成虚拟物料信息
			createPath(pmdd, validpath, idx);

		}
	}

	/**
	 * 创建后续虚拟物料信息
	 * 
	 * @param pmds      虚拟物料集合
	 * @param idx
	 * @param validpath
	 * @throws Exception
	 */
	public void createPath(List<PlnMaterielDetail> pmds, ArrayList<String> validpath, int idx) throws Exception {

		for (PlnMaterielDetail match : pmds) {
			// 如果 obj_vt 无任何 虚拟子物料，则根据工艺路径，新建后续虚拟物料信息：
			// Design_Plan_Info（生产订单号，新工序路径数组,idx，obj_vt，单重）
			List<PlnMaterielDetail> child_m = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + match.getObject_no_vt() + "' and nvl(invalid_flg,0) != 1 ", "", 0, 0);
			if (Utils.isEmpty(child_m)) {
				if (idx + 1 <= validpath.size()) {
					// 调用设计信息接口
					List<DesignInfo> infos = new ArrayList<DesignInfo>();
					DesignInfo info = new DesignInfo();
					info.setCurrentProcIndex(idx);
					info.setObject_no(match.getObject_no());
					info.setObject_no_vt(match.getObject_no_vt());
					info.setProcess(validpath);
					info.setProd_order_no(match.getProd_order_no());
					info.setSingle_wgt(match.getSingle_weight());
					infos.add(info);
					ResultModel result = Design_Plan_Info(infos, null);
					if ("500".equals(result.getState())) {
						throw new Exception(result.getMsgInfo());
					}
					// 修改库存状态成品库至在制成品库
					YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).findById(match.getObject_no());
					if ("500203".equals(ypd.getStorageattr())) {
//						ypd.setStorageattr("500203");
						CommonPage<YdmProductDetail> cp = new CommonPage<YdmProductDetail>();
						List<YdmProductDetail> ydm = new ArrayList<YdmProductDetail>();
						ydm.add(ypd);
						ypd.setMemo("订单变更增加工序->移至在制库");
						cp.setObjectList(ydm);
						cp.setMemo1("500202");
						cp.setMemo2("-1");
						this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(cp);
					}

				} else {
					// 修改当前物料库存信息与虚拟物料信息
					match.setNext_dsn_process_code("");
					match.setNext_process_code("");
					this.getMapper(PlnMaterielDetailMapper.class).update(match);

					// 修改库存状态在制品库至成品库
					YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).findById(match.getObject_no());
					if ("500202".equals(ypd.getStorageattr())) {
//					ypd.setStorageattr("500203");
						CommonPage<YdmProductDetail> cp = new CommonPage<YdmProductDetail>();
						List<YdmProductDetail> ydm = new ArrayList<YdmProductDetail>();
						ypd.setMemo("删除工序->移至成品库");
						ydm.add(ypd);
						cp.setObjectList(ydm);
						cp.setMemo1("500203");
						cp.setMemo2("0");
						this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(cp);
					}
				}
				// 有子卷
			} else {
				createPath(child_m, validpath, idx + 1);
			}
		}
	}

	/**
	 * 删除未挂单虚拟物料信息
	 * 
	 * @param pmds      虚拟物料集合
	 * @param validpath
	 * @param idx
	 * @throws Exception
	 */
	public void deletePath(List<PlnMaterielDetail> pmds, ArrayList<String> validpath, int idx) throws Exception {

		for (PlnMaterielDetail ppp : pmds) {

			// 获取子卷信息
			List<PlnMaterielDetail> child = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + ppp.getObject_no_vt() + "' and nvl(invalid_flg,0) != 1 ", "", 0, 0);
			// 有子卷
			if (Utils.isNotEmpty(child)) {
				deletePath(child, validpath, idx + 1);
			}
			// 判断本身是否删除未挂单删除
			if (ppp.getObject_no() == null) {
				this.getMapper(PlnMaterielDetailMapper.class).doDeleteId(ppp);
			}
		}
	}

	/**
	 * 
	 * 获取工艺路径类
	 * 
	 * @param process
	 * @return
	 */
	public List<ProcessUtils> getprcUtls(String process) {
		List<ProcessUtils> old_proc = new ArrayList<ProcessUtils>();
		String[] path = process.split("-");
		int index = 0;
		ArrayList<String> validpath = getProcessPath(path);
		if (Utils.isNotEmpty(validpath)) {
			for (String str : validpath) {
				ProcessUtils pro = new ProcessUtils();
				pro.setProc_code(str);
				pro.setProc_index(index++);
				pro.setProc_name(this.getMapper(ComBaseProcessRStationMapper.class)
						.findWithCondition(null, "process_code = '" + str + "' and validflag = '1'", null, 0, 1).get(0)
						.getProcess_point_desc());
				pro.setRepeat_times(0);
				pro.setStatus("0");
				old_proc.add(pro);
			}
		}
		return old_proc;
	}

	/**
	 * 修改生产订单状态
	 * 
	 * @param order_no 合同号+合同行序号+订单行序号
	 * @throws Exception
	 */
	public void updateOrderStatus(String order_no) throws Exception {
		// 获取生产订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"order_no = '" + order_no + "'", "", 0, 0);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("未找到生产订单信息!");
		}
		// 锁定生产订单状态 2
		this.getMapper(PlnProdorderMapper.class).updateOrderStatus(order_no);
	}

	/**
	 * 生产订单是否锁定
	 * 
	 * @param prod_order_no
	 * @return
	 */
	public boolean pOrdIsLocked(String prod_order_no) {
		boolean flag = false;
		// 查询生产订单是否是锁定状态
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"prod_order_no = '" + prod_order_no + "' and nvl(finished_status,0) = 2 ", "", 0, 1);
		if (Utils.isNotEmpty(ppo)) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 厂内合同与否
	 * 
	 * @param prod_order_no 生产订单号
	 * @return
	 * @throws Exception
	 */
	public boolean getContractType(String prod_order_no) throws Exception {
		boolean flag = false;
		// 获取订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"prod_order_no = '" + prod_order_no + "'", "", 0, 1);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("未找到生产订单[" + prod_order_no + "]信息!");
		}
		if (Utils.isNotEmpty(ppo) && "101603".equals(ppo.get(0).getContract_type_no())) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 来料加工合同与否
	 * 
	 * @param prod_order_no 生产订单号
	 * @return
	 * @throws Exception
	 */
	public boolean getCont_Type(String prod_order_no) throws Exception {
		boolean flag = false;
		// 获取订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"prod_order_no = '" + prod_order_no + "'", "", 0, 1);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("未找到生产订单[" + prod_order_no + "]信息!");
		}
		if (Utils.isNotEmpty(ppo) && "101606".equals(ppo.get(0).getContract_type_no())) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 物料是否生产完成
	 * 
	 * @param object_no
	 * @return
	 */
	public boolean matIsFinish(String object_no) {
		boolean flag = false;
		// 获取物料附加信息
		PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class).findById(object_no);
		if (Utils.isNotEmpty(pme) && Utils.isNotEmpty(pme.getActual_process())
				&& Utils.isNotEmpty(pme.getTask_process_codes())
				&& pme.getActual_process().contains(pme.getTask_process_codes())) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 物料充当脱单履历
	 * 
	 * @param pmd       虚拟物料信息
	 * @param remark    备注
	 * @param userName  操作人
	 * @param process   工序
	 * @param opt_type  操作类型
	 * @param object_no 物料号
	 */
	public void createMatLog(PlnMaterielDetail pmd, String remark, String userName, String process, String opt_type,
			String object_no) {
		List<PlnMatReplaceLog> lmmrl = this.getMapper(PlnMatReplaceLogMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long iNo = 1;
		if (lmmrl != null && lmmrl.size() > 0) {
			iNo = lmmrl.get(0).getSerial_no() + 1;
		}
		// 物料充当脱单履历表
		PlnMatReplaceLog mmrl = new PlnMatReplaceLog();
		BeanUtils.copyProperties(pmd, mmrl);
		mmrl.setSerial_no(iNo++);
		mmrl.setObject_no(object_no);
		mmrl.setOpt_type(opt_type);
		mmrl.setCreate_man_name(userName);
		mmrl.setCreate_time(new Date());
		mmrl.setProcess(process);
		mmrl.setRemark(remark);
		this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
	}

	/**
	 * 当前工序是否存在成分材质工序点
	 * 
	 * @param object_no_vt 虚拟物料号
	 * @param process_code 当前工序代码 E/D/C
	 * @return
	 * @throws Exception
	 */
	public boolean iON_Contain_COC(String object_no_vt, String process_code) throws Exception {
		boolean flag = false;
		// 获取虚拟物料信息
		List<PlnMaterielDetail> lpmdc = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,'0') = '0'", null, 0, 1);
		if (Utils.isEmpty(lpmdc)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt + "]信息");
		}
		// 获取生产订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"prod_order_no = '" + lpmdc.get(0).getProd_order_no() + "'", "", 0, 1);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt + "]对应的订单信息");
		}
		// 有结果说明有材质/成分类工序点
		List<SlmOrdDesignMscPlSti> listSti = this.getMapper(SlmOrdDesignMscPlStiMapper.class).findWithCondition(null,
				" design_key = '" + ppo.get(0).getDesign_key() + "'  AND MSC_PLINE = '" + ppo.get(0).getMsc_pline()
						+ "' and process_code = '" + process_code + "' and PROCESS_POINT_TYPE in ('403201','403202')",
				"  BACKLOG_SEQ, PROCESS_POINT_SEQ", 0, 0);
		// 全制程工序点信息存在
		if (listSti != null && listSti.size() > 0) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 能否组检验批
	 * 
	 * @param object_no_vt1 虚拟物料号1
	 * @param object_no_vt2 虚拟物料号2
	 * @param process_code  当前工序
	 * @return
	 * @throws Exception
	 */
	public boolean iON_doGroup(String object_no_vt1, String object_no_vt2, String process_code) throws Exception {
		boolean flag = true;
		// 获取工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		// 获取虚拟物料信息
		List<PlnMaterielDetail> pmd1 = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + object_no_vt1 + "' and nvl(invalid_flg,'0') = '0'", null, 0, 1);
		List<PlnMaterielDetail> pmd2 = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + object_no_vt2 + "' and nvl(invalid_flg,'0') = '0'", null, 0, 1);
		if (Utils.isEmpty(pmd1)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt1 + "]信息");
		}
		if (Utils.isEmpty(pmd2)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt2 + "]信息");
		}
		// 获取实物信息
		YdmProductDetail ypd1 = this.getMapper(YdmProductDetailMapper.class).findById(pmd1.get(0).getObject_no());
		YdmProductDetail ypd2 = this.getMapper(YdmProductDetailMapper.class).findById(pmd2.get(0).getObject_no());
		if (Utils.isEmpty(ypd1)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt1 + "]所挂的实物[" + pmd1.get(0).getObject_no() + "]信息");
		}
		if (Utils.isEmpty(ypd2)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt2 + "]所挂的实物[" + pmd2.get(0).getObject_no() + "]信息");
		}
		// 获取检验批重量限制
		List<ComBaseInfo> cba = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"base_code = '200901'  and validflag = '1'", "", 0, 1);
		if (ypd1.getFactweight().doubleValue()
				+ ypd2.getFactweight().doubleValue() > Double.parseDouble(cba.get(0).getMemo()) * 1000) {
			return false;
		}
		// 当前工序的获取校验项目
		List<ComBaseInfo> cbi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2009' and memo like '%" + process_code + "%' and validflag = '1'", "", 0, 0);
		for (ComBaseInfo com : cbi) {

			// 牌号一致性检验
			if ("200902".equals(com.getBase_code())) {
				if (!ypd1.getSteelcode().equals(ypd2.getSteelcode())) {
					return false;
				}
			}
			// 尺寸一致性校验(厚宽)
			if ("200903".equals(com.getBase_code())) {
				if (ypd1.getThick().doubleValue() != ypd2.getThick().doubleValue()
						|| ypd1.getWidth().doubleValue() != ypd2.getWidth().doubleValue()) {
					return false;
				}
			}
			// 经过退火工序并且炉号一致
			if ("200904".equals(com.getBase_code())) {
				// 获取物料附加信息
				PrcMaterielExtinfo pmex1 = this.getMapper(PrcMaterielExtinfoMapper.class)
						.findById(pmd1.get(0).getObject_no());
				PrcMaterielExtinfo pmex2 = this.getMapper(PrcMaterielExtinfoMapper.class)
						.findById(pmd2.get(0).getObject_no());
				if (Utils.isNotEmpty(pmex1) && Utils.isNotEmpty(pmex2) && Utils.isNotEmpty(pmex1.getActual_process())
						&& Utils.isNotEmpty(pmex2.getActual_process())) {
					if (pmex1.getActual_process().contains(processpoint.anneal_code)
							&& pmex2.getActual_process().contains(processpoint.anneal_code) && ypd1.getHeatno() != null
							&& ypd2.getHeatno() != null && ypd1.getHeatno().equals(ypd2.getHeatno())) {
						return false;
					}
				}
			}
		}
		return flag;
	}

	/**
	 * 物料能否加入检验批
	 * 
	 * @param object_no_vt 虚拟物料号
	 * @param plan_no      计划号
	 * @param process_code 当前工序
	 * @return
	 * @throws Exception
	 */
	public boolean iON_MatInPlan(PlnMaterielDetail pln, String plan_no) throws Exception {
		boolean flag = false;
		// 获取待比较虚拟物料信息
		List<PlnMaterielDetail> pmdd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + pln.getObject_no_vt() + "' and nvl(invalid_flg,0) <> 1", "", 0, 1);
		double wgt = pmdd.get(0).getSingle_weight().doubleValue();
		// 获取计划内所有的虚拟物料信息
		String str = "nvl(invalid_flg,0) <> 1 and mat_object_no_vt is null ";
		// 获取工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		if (processpoint.slitting_code.equals(pln.getNext_process_code())) {
			str += "and lw_plan_no = '" + plan_no + "'";
		} else if (processpoint.cross_cutting_code.equals(pln.getNext_process_code())) {
			str += "and cl_plan_no = '" + plan_no + "'";
		} else if (processpoint.smooth_code.equals(pln.getNext_process_code())) {
			str += "and sr_plan_no = '" + plan_no + "'";
		} else if (processpoint.anneal_code.equals(pln.getNext_process_code())) {
			str += "and an_plan_no = '" + plan_no + "'";
		} else if (processpoint.rolling_code.equals(pln.getNext_process_code())) {
			str += "and rl_plan_no = '" + plan_no + "'";
		} else if (processpoint.pickle_code.equals(pln.getNext_process_code())) {
			str += "and pc_plan_no = '" + plan_no + "'";
		}
		List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, str, "", 0,
				0);
		// 当前工序的获取校验项目
		List<ComBaseInfo> cbi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"base_code = '200901'  and validflag = '1'", "", 0, 1);
		if (Utils.isNotEmpty(pmd)) {
			for (PlnMaterielDetail pd : pmd) {
				wgt += pd.getSingle_weight().doubleValue();
				flag = iON_doGroup(pln.getObject_no_vt(), pd.getObject_no_vt(), pd.getNext_process_code());
			}
			if (wgt > Double.parseDouble(cbi.get(0).getMemo()) * 1000) {
				return false;
			}
		}
		return flag;

	}

	/**
	 * 编制计划：分条
	 * 
	 * @param oci 虚拟物料号,下一个工序点 必传
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel planing(CommonPage<PlnMaterielDetail> oci) throws Exception {
		ResultModel rm = new ResultModel("200", "计划编制成功!");
		List<PlnMaterielDetail> lpmd = oci.getObjectList();
		String plan_no = "";
		List<String> plan_g = new ArrayList<String>();
		boolean first_f = false;
		// 获取工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		String tgMsg = null;
		// 循环比较虚拟物料信息
		for (PlnMaterielDetail pln : lpmd) {
			
			// 直接在这里获取库存卷是否已经有综判：不存在则直接跳过，并记录哪个卷跳过了20231106刘侣
			List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no_vt = '"+pln.getObject_no_vt()+"' and nvl(invalid_flg,0) =0", null, 0, 1);
			YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).findById(lpmdq.get(0).getObject_no());
			if (StringUtils.isEmpty(ypd.getJudgeresult())) {
				// throw new Exception("物料【"+ypd.getCoilno()+"】还未进行综合判定，不能编制计划");
				tgMsg += (ypd.getCoilno() + "; ");
				continue;
			}
			// end
			
			// 是否包含成分材质检验工序点
			boolean flag = iON_Contain_COC(pln.getObject_no_vt(), pln.getNext_process_code());
			if (flag) {
				// 第一个虚拟物料直接生成计划
				if (!first_f) {
					first_f = true;
					plan_no = createPlan(pln, oci.getMemo1(), oci.getMemo2(),oci.getMemo6());
					plan_g.add(plan_no);
				} else {
					// 物料否加入检验批
					boolean flag_ig = false;
					for (String str : plan_g) {
						boolean ionmatch = iON_MatInPlan(pln, str);
						if (ionmatch) {
							flag_ig = true;
							if (processpoint.slitting_code.equals(pln.getNext_process_code())) {
								pln.setLw_plan_no(plan_no);
							} else if (processpoint.cross_cutting_code.equals(pln.getNext_process_code())) {
								pln.setCl_plan_no(plan_no);
							} else if (processpoint.smooth_code.equals(pln.getNext_process_code())) {
								pln.setSr_plan_no(plan_no);
							} else if (processpoint.anneal_code.equals(pln.getNext_process_code())) {
								pln.setAn_plan_no(plan_no);
							} else if (processpoint.rolling_code.equals(pln.getNext_process_code())) {
								pln.setRl_plan_no(plan_no);
							} else if (processpoint.pickle_code.equals(pln.getNext_process_code())) {
								pln.setPc_plan_no(plan_no);
							}
							createPlan(pln, oci.getMemo1(), oci.getMemo2(),oci.getMemo6());
							break;
						}
					}
					// 不能组批则新建
					if (!flag_ig) {
						plan_g.add(createPlan(pln, oci.getMemo1(), oci.getMemo2(),oci.getMemo6()));
					}
				}
			} else {
				// 不包含成分材质,单独生成计划
				createPlan(pln, oci.getMemo1(), oci.getMemo2(),oci.getMemo6());
			}
		}
		
		if (tgMsg != null) {
			rm.setMsgInfo("卷: " + tgMsg + " 没综判未成功，其他计划编制成功"); 
		}
		
		return rm;
	}

	/**
	 * 生成计划
	 * @param pln   虚拟物料信息
	 * @param memo1 计划编制时间
	 * @param memo2 机台代码 (平整和开平)
	 * @return 返回计划号
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public String createPlan(PlnMaterielDetail pln, String memo1, String memo2,String memo6) throws Exception {
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no_vt = '"+pln.getObject_no_vt()+"' and nvl(invalid_flg,0) =0", null, 0, 1);
		if (Utils.isEmpty(lpmdq)) {
			throw new Exception("未找到虚拟物料["+pln.getObject_no_vt()+"]信息！");
		}
		YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).findById(lpmdq.get(0).getObject_no());
		if (StringUtils.isEmpty(ypd.getJudgeresult())) {
			throw new Exception("物料【"+ypd.getCoilno()+"】还未进行综合判定，不能编制计划");
		}	
		
		List<PlnProdorder> ppoL = this.getMapper(PlnProdorderMapper.class).findWithCondition(null, " ORDER_NO='"+ypd.getOrderno()+"'", null, 0, 0);
		if (ppoL == null || ppoL.size() <= 0) {
			throw new Exception("生产订单：" + ypd.getOrderno() + " 不存在");
		}
		// 验证生产订单状态是否为订单保留：
		if ("0PAA60".equals(ppoL.get(0).getStatus())) {
			throw new Exception("生产订单["+ppoL.get(0).getProd_order_no()+"]为 ‘订单保留’ 状态，不允许进行计划编制");
		}
		if ("0PAA70".equals(ppoL.get(0).getStatus())) {
			throw new Exception("生产订单["+ppoL.get(0).getProd_order_no()+"]为 ‘订单作废’ 状态，不允许进行计划编制");
		}
		
		// 获取工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' and validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		// 不包含成分材质,单独生成计划
		ResultModel sg_rm = new ResultModel();
		MesOprLog mol = null;
		CommonPage<PlnMaterielDetail> cp = new CommonPage<PlnMaterielDetail>();
		List<PlnMaterielDetail> sg_tmp = new ArrayList<PlnMaterielDetail>();
		sg_tmp.add(pln);
		cp.setObjectList(sg_tmp);
		cp.setMemo1(memo1);
		cp.setMemo2(memo2);
		cp.setMemo6(memo6);//计划加工时间
		if (processpoint.slitting_code.equals(pln.getNext_process_code())) {			//4mm 12mm
			sg_rm = this.getBean(PlnLengthwisePlanServiceImpl.class).doCheckPlanAdd(cp); 
			mol = new MesOprLog("生产管理", "分条计划编制", "编制计划", userName, opr_time, ypd.getCoilno(), null, null, null, null);
		} else if (processpoint.cross_cutting_code.equals(pln.getNext_process_code())) {//3mm
			sg_rm = this.getBean(PlnCuttolengthPlanServiceImpl.class).doCheckPlanAdd(cp);
			mol = new MesOprLog("生产管理", "开平计划编制", "编制计划", userName, opr_time, ypd.getCoilno(), null, null, null, null);
		} else if (processpoint.smooth_code.equals(pln.getNext_process_code())) {		//平整
			sg_rm = this.getBean(PlnSkinrollingDsnMultinfoServiceImpl.class).doCheckPlanAdd(cp);
			mol = new MesOprLog("生产管理", "平整计划编制", "编制计划", userName, opr_time, ypd.getCoilno(), null, null, null, null);
		} else if (processpoint.anneal_code.equals(pln.getNext_process_code())) { 		//退火
			sg_rm = this.getBean(PlnAnnealDsnMultinfoServiceImpl.class).doCheckPlanAdd(cp);
			mol = new MesOprLog("生产管理", "退火计划编制", "编制计划", userName, opr_time, ypd.getCoilno(), null, null, null, null);
		} else if (processpoint.rolling_code.equals(pln.getNext_process_code())) {		//轧机
			sg_rm = this.getBean(PlnRollingDsnMultinfoServiceImpl.class).doCheckPlanAdd(cp);
			mol = new MesOprLog("生产管理", "轧制计划编制", "编制计划", userName, opr_time, ypd.getCoilno(), null, null, null, null);
		} else if (processpoint.pickle_code.equals(pln.getNext_process_code())) {		//酸洗
			sg_rm = this.getBean(PlnPickleDsnMultinfoServiceImpl.class).doCheckPlanAdd(cp);
			mol = new MesOprLog("生产管理", "酸洗计划编制", "编制计划", userName, opr_time, ypd.getCoilno(), null, null, null, null);
		}
		if (!"200".equals(sg_rm.getState())) {
			throw new Exception(sg_rm.getMsgInfo());
		}
		//新增日志记录
		this.getMapper(MesOprLogMapper.class).insert(mol);
		return String.valueOf(sg_rm.getData());
	}

	/**
	 * 获取平整子卷重量数组
	 * 
	 * @param mat_wgt   原料重量
	 * @param plate_wgt 成品重量
	 * @return
	 */
	public ArrayList<Double> howToSr(double mat_wgt, double plate_wgt) {
		ArrayList<Double> result = new ArrayList<Double>();
		// 原料重量/成品重量四舍五入取整
		int c_num = (int) Math.round(DoubleUtil.div(mat_wgt, plate_wgt));
		if (c_num == 1 || c_num < 1) {
			result.add(mat_wgt);
		} else if (c_num == 2) {
			result.add(plate_wgt);
			result.add(DoubleUtil.sub(mat_wgt, plate_wgt));
		} else {
			double tmp = 0;
			for (int i = 0; i < c_num - 1; i++) {
				result.add(plate_wgt);
				tmp += plate_wgt;
			}
			result.add(DoubleUtil.sub(mat_wgt, tmp));
		}
		return result;
	}

	/**
	 * 获取子卷的母卷集合 以及判定信息和工序信息
	 * 
	 * @param object_no
	 * @return
	 * @throws Exception
	 */
	public List<Judge_Prc_Info> getMatList(String object_no) throws Exception {
		if (Utils.isEmpty(object_no))
			throw new Exception("请传入物料号!");
		List<Judge_Prc_Info> result = this.getMapper(PrcMaterielProcessMapper.class).findMatInfo(object_no);
		if (Utils.isNotEmpty(result)) {
			for (Judge_Prc_Info ydm : result) {
				// 获取物料对应质量设计信息的工序序号
				SlmOrdDesignMscPlSti tmp = getPrc_Code_Of_Mat(ydm.getObject_no());
				long backlog_seq = 0 ;
				if(Utils.isNotEmpty(tmp)) {
					backlog_seq = tmp.getBacklog_seq();
				}else {
					continue ;
				}
				// 通过design_key 和全程产险码获取质量设计信息
				List<SlmOrdDesignMscPlSti> listSti = this.getMapper(SlmOrdDesignMscPlStiMapper.class).findWithCondition(
						null,
						" design_key = '" + ydm.getDesign_key() + "' and msc_pline = '" + ydm.getMsc_pline()
								+ "' and process_code = '" + ydm.getProcess_code() + "' and BACKLOG_SEQ = '"
								+ backlog_seq + "'",
						" BACKLOG_SEQ ,process_point_seq ", 0, 0);
				if (Utils.isEmpty(listSti)) {
					return result;
				} else { 
					BeanUtils.copyProperties(listSti.get(0), ydm);
					ydm.setListSti(listSti);
				}
			}
		}
		return result;
	}

	/**
	 * 给计划模块的接口获取全程产线码以及对应的工艺路径
	 * 
	 * @param design_key
	 * @return 2018-09-03 zhangjiao
	 */
	public ResultModel GetMscByDesignKey(String design_key) {
		ResultModel rm = new ResultModel();
		try {
			if (design_key == null || "".equals(design_key)) {
				rm.setState("500");
				rm.setMsgInfo("参数不正确");
				return rm;
			}
			SlmOrdDesignMscPl _pl = new SlmOrdDesignMscPl();
			_pl.setDesign_key(design_key);
			List<SlmOrdDesignMscPl> listPl = this.getMapper(SlmOrdDesignMscPlMapper.class).find(_pl, 0, 0);
			if (listPl == null || listPl.size() < 1) {
				rm.setState("500");
				rm.setMsgInfo("未查询[" + design_key + "]到匹配的制程信息!");
				return rm;
			}
			// and (process_code = 'B' OR process_code = 'D')
			List<SlmOrdDesignMscPlSti> listSti = this.getMapper(SlmOrdDesignMscPlStiMapper.class).findWithCondition(
					null, " design_key = '" + design_key + "'", " BACKLOG_SEQ,PROCESS_POINT_SEQ ", 0, 0);
			if (listSti == null || listSti.size() < 1) {
				rm.setState("500");
				rm.setMsgInfo("未查询[" + design_key + "]匹配的制程信息!");
				return rm;
			}
			for (SlmOrdDesignMscPl mscPl : listPl) {
				StringBuilder sb = new StringBuilder("");
				StringBuilder sb2 = new StringBuilder("");
				StringBuilder sb3 = new StringBuilder("");
				List<SlmOrdDesignMscPlSti> stition = new ArrayList<SlmOrdDesignMscPlSti>();
				for (SlmOrdDesignMscPlSti slmOrdDesignMscPlSti : listSti) {
					if (slmOrdDesignMscPlSti.getMsc_pline().equals(mscPl.getMsc_pline())) {
						sb2.append("-" + slmOrdDesignMscPlSti.getProcess_point_code());
						sb.append("-" + slmOrdDesignMscPlSti.getProcess_point_desc());
						sb3.append("-" + slmOrdDesignMscPlSti.getBacklog_seq());
						stition.add(slmOrdDesignMscPlSti);
					}
				}
				mscPl.setStition(stition);
				mscPl.setStations_code(stition.get(0).getWhole_backlog());
				String[] str = stition.get(0).getWhole_backlog().split("-");
				ArrayList<String> validpath = new ArrayList<String>(Arrays.asList(str));
				mscPl.setStations_desc(getpath_name(validpath));
				mscPl.setWarn_desc(sb3.toString().replaceFirst("-", ""));

			}
			rm.setData(listPl);
			rm.setState("200");
		} catch (Exception e) {
			rm.setState("500");
			rm.setMsgInfo("获取全程产线号失败");
			rm.setErrorInfo(e.getMessage());
		}
		return rm;
	}

	/**
	 * 获取物料当前执行工序/序号/全程产品码
	 * 
	 * @param object_no 物料号
	 * @return
	 */
	public SlmOrdDesignMscPlSti getPrc_Code_Of_Mat(String object_no) throws Exception {
		// 获取物料附加信息
		// 原料卷不考虑
		if(object_no.length() <=8) {
			return null ;
		}
		String prc_code = "" , prod_order_no = "";
		// 获取虚拟物料信息
		if (Utils.isEmpty(object_no))
			throw new Exception("请传入物料号!");
		List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				" object_no = '" + object_no + "' and nvl(invalid_flg,0) <> 1 ", "", 0, 1);
		if (Utils.isEmpty(pmd)) {
			// 获取物料挂单信息
			List<PlnMatReplaceLog> pmr = this.getMapper(PlnMatReplaceLogMapper.class)
					.findWithCondition(null, "object_no = '"+object_no+"' and opt_type in('1','2')", " create_time desc ", 0, 1);
			if(Utils.isNotEmpty(pmr)) {
				prod_order_no = pmr.get(0).getProd_order_no();
			}else {
				return null;
			}
			// 获取物料附加信息 
			PrcMaterielExtinfo pme = this.getMapper(PrcMaterielExtinfoMapper.class).findById(object_no);
			if(Utils.isNotEmpty(pme)) {
				if(pme.getActual_process().contains("-")) {
					prc_code = StringUtils.substringAfterLast(pme.getActual_process(), "-");
				} else {
					prc_code = pme.getActual_process() ;
				}
			}
		}else {
			prod_order_no = pmd.get(0).getProd_order_no();
			prc_code = pmd.get(0).getPrev_process_code() == null ? pmd.get(0).getNext_process_code()
					: pmd.get(0).getPrev_process_code();
		}
		SlmOrdDesignMscPlSti result = new SlmOrdDesignMscPlSti();
		result.setProcess_code(prc_code);
		// 获取订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"prod_order_no = '" + prod_order_no + "'", "", 0, 1);
		if (Utils.isEmpty(ppo))
			return null;
		// 整卷发运
		if("1".equals(ppo.get(0).getWhole_coil())) {
			result.setWhole_coil(ppo.get(0).getWhole_coil());
			return result ;
		}
		// 如果没获取到当前的工序信息
		if(prc_code == "")
			return null;
		result.setMsc_pline(ppo.get(0).getMsc_pline());
		// 通过design_key 和全程产险码以及工序点代码获取工序序号
		SlmOrdDesignMscPlSti sti = new SlmOrdDesignMscPlSti();
		sti.setDesign_key(ppo.get(0).getDesign_key());
		sti.setMsc_pline(ppo.get(0).getMsc_pline());
		sti.setProcess_code(prc_code);
		List<SlmOrdDesignMscPlSti> listSti = this.getMapper(PlnProdorderExtinfoMapper.class).getQcmPrcInfo(sti);
		if (Utils.isEmpty(listSti))
			return null;
		result = listSti.get(0);
		if (Utils.isEmpty(pmd.get(0).getProc_repeat_index())) {
			// 获取母卷虚拟物料信息
			List<PlnMaterielDetail> pmd_M = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + pmd.get(0).getMat_object_no_vt() + "' and nvl(invalid_flg,0) <> 1 ", "", 0,
					1);
			if (Utils.isEmpty(pmd_M) || listSti.size() < pmd_M.get(0).getProc_repeat_index()) {
				return null;
			} else if (listSti.size() >= pmd_M.get(0).getProc_repeat_index()) {
				result = listSti.get(pmd_M.get(0).getProc_repeat_index() - 1);
			}
		} else if (listSti.size() >= pmd.get(0).getProc_repeat_index() && pmd.get(0).getProc_repeat_index() > 1) {
			result = listSti.get(pmd.get(0).getProc_repeat_index() - 1);
		}
		return result;
	}

	/**
	 * 获取虚拟物料的工序信息
	 * 
	 * @param object_no_vt
	 * @return
	 * @throws Exception
	 */
	public SlmOrdDesignMscPlSti getPrc_Info_Of_Obvt(String object_no_vt) throws Exception {

		SlmOrdDesignMscPlSti rst = new SlmOrdDesignMscPlSti();
		// 获取虚拟物料信息
		List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				" object_no_vt = '" + object_no_vt + "'", null, 0, 1);
		if (Utils.isEmpty(pmd))
			return null;
		// 工序信息
		String prc_code;
		if (pmd.get(0).getPrev_process_code() != null && pmd.get(0).getNext_process_code() != null) {
			prc_code = get_Prc_Code(pmd.get(0).getStatus());
		} else {
			prc_code = pmd.get(0).getPrev_process_code() == null ? pmd.get(0).getNext_process_code()
					: pmd.get(0).getPrev_process_code();
		}
		// 获取订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"prod_order_no = '" + pmd.get(0).getProd_order_no() + "'", "", 0, 1);
		if (Utils.isEmpty(ppo))
			return null;
		// 通过design_key 和全程产险码以及工序代码获取工序序号
		SlmOrdDesignMscPlSti sti = new SlmOrdDesignMscPlSti();
		sti.setDesign_key(ppo.get(0).getDesign_key());
		sti.setMsc_pline(ppo.get(0).getMsc_pline());
		sti.setProcess_code(prc_code);
		List<SlmOrdDesignMscPlSti> listSti = this.getMapper(PlnProdorderExtinfoMapper.class).getQcmPrcInfo(sti);
		if (Utils.isEmpty(listSti))
			return null;
		rst = listSti.get(0);
		if (Utils.isEmpty(pmd.get(0).getProc_repeat_index())) {
			// 获取母卷虚拟物料信息
			List<PlnMaterielDetail> pmd_M = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + pmd.get(0).getMat_object_no_vt() + "' and nvl(invalid_flg,0) <> 1 ", "", 0,
					1);
			if (Utils.isEmpty(pmd_M) || listSti.size() < pmd_M.get(0).getProc_repeat_index()) {
				return null;
			} else if (listSti.size() >= pmd_M.get(0).getProc_repeat_index()) {
				rst = listSti.get(pmd_M.get(0).getProc_repeat_index() - 1);
			}
		} else if (listSti.size() >= pmd.get(0).getProc_repeat_index() && pmd.get(0).getProc_repeat_index() > 1) {
			rst = listSti.get(pmd.get(0).getProc_repeat_index() - 1);
		}
		return rst;

	}

	/**
	 * 比较工艺标准
	 * 
	 * 入口厚度可能只有上限或者下限所以赋了初值
	 * 
	 * @param tics
	 */
	public void comp_Proc_Std(List<SlmOrdDesignMscTic> tics) throws Exception {
		double ithk_min_f = 0, ithk_max_f = 99, ithk_min_n = 0, ithk_max_n = 99, othk_min_f = 0, othk_max_f = 99,
				othk_min_n = 0, othk_max_n = 99;
		CommonPage<SlmOrdDesignMscTic> com = new CommonPage<SlmOrdDesignMscTic>();
		// 第一道次轧制
		com.setObject(tics.get(0));
		ResultModel tic_f = this.getBean(QmsApiServiceImpl.class).getGongYi(com);
		if ("500".equals(tic_f.getState())) {
			throw new Exception("获取[" + tics.get(0).getProcess_point_desc() + "]工艺标准失败!" + tic_f.getMsgInfo());
		}
		List<SlmOrdDesignMscTicItem> item_f = (List<SlmOrdDesignMscTicItem>) tic_f.getData();
		// 获取轧制入口厚度出口厚度的代码
		List<PbModelDb> code = getBase_Name("201001");
		for (SlmOrdDesignMscTicItem slmO : item_f) {
			// 入口厚度
			if (slmO.getCraft_param_code().equals(code.get(0).getText())) {
				if (slmO.getMin_value() == null && slmO.getMax_value() == null) {
					throw new Exception("未获取到工艺参数入口厚度,请重新质量设计!");
				}
				ithk_min_f = Double.valueOf(slmO.getMin_value() == null ? "0" : slmO.getMin_value());
				if (Utils.isNotEmpty(slmO.getMax_value())) {
					ithk_max_f = Double.valueOf(slmO.getMax_value());
				}
				continue;
			}
			// 出口厚度
			if (slmO.getCraft_param_code().equals(code.get(1).getText())) {
				if (slmO.getMin_value() == null && slmO.getMax_value() == null) {
					throw new Exception("未获取到工艺参数出口厚度,请重新质量设计!");
				}
				othk_min_f = Double.valueOf(slmO.getMin_value() == null ? "0" : slmO.getMin_value());
				if (Utils.isNotEmpty(slmO.getMax_value())) {
					othk_max_f = Double.valueOf(slmO.getMax_value());
				}
				continue;
			}
		}

		for (int i = 1; i < tics.size(); i++) {
			CommonPage<SlmOrdDesignMscTic> com_n = new CommonPage<SlmOrdDesignMscTic>();
			com_n.setObject(tics.get(i));
			ResultModel tic_n = this.getBean(QmsApiServiceImpl.class).getGongYi(com_n);
			if ("500".equals(tic_n.getState())) {
				throw new Exception("获取[" + tics.get(i).getProcess_point_desc() + "]工艺标准失败!" + tic_n.getMsgInfo());
			}
			List<SlmOrdDesignMscTicItem> item_n = (List<SlmOrdDesignMscTicItem>) tic_f.getData();
			for (SlmOrdDesignMscTicItem slm : item_n) {
				// 入口厚度
				if (slm.getCraft_param_code().equals(code.get(0).getText())) {
					if (slm.getMin_value() == null && slm.getMax_value() == null) {
						throw new Exception("未获取到工艺参数入口厚度,请重新质量设计!");
					}
					ithk_min_n = Double.valueOf(slm.getMin_value() == null ? "0" : slm.getMin_value());
					ithk_max_n = Double.valueOf(slm.getMax_value());
					continue;
				}
				// 出口厚度
				if (slm.getCraft_param_code().equals(code.get(1).getText())) {
					if (slm.getMin_value() == null && slm.getMax_value() == null) {
						throw new Exception("未获取到工艺参数出口厚度,请重新质量设计!");
					}
					othk_min_n = Double.valueOf(slm.getMin_value() == null ? "0" : slm.getMin_value());
					othk_max_n = Double.valueOf(slm.getMax_value());
					continue;
				}
			}
			// 比较两个区间是否有公共区间
			if (Utils.getInterval_min(othk_min_f, othk_max_f, ithk_min_n, ithk_max_n) == -1.0) {
				throw new Exception("第" + i + "次[" + tics.get(i).getProcess_point_desc() + "]的出口厚度[" + othk_min_f + ","
						+ othk_max_f + "]和第" + i + 1 + "次[" + tics.get(i).getProcess_point_desc() + "]的入口厚度["
						+ ithk_min_n + "," + ithk_max_n + "]不匹配!");
			}
			othk_min_f = othk_min_n;
			othk_max_f = othk_max_n;
		}
	}

	/**
	 * 校验第一个道次的入口厚度是否大于订单厚度
	 * 
	 * @param tics
	 * @param thick 订单要求厚度
	 * @throws Exception
	 */
	public void checkFirstProc(List<SlmOrdDesignMscTic> tics, double thick) throws Exception {

		double ithk_min_f = 0, ithk_max_f = 99;
		CommonPage<SlmOrdDesignMscTic> com = new CommonPage<SlmOrdDesignMscTic>();
		// 第一道次轧制
		com.setObject(tics.get(0));
		ResultModel tic_f = this.getBean(QmsApiServiceImpl.class).getGongYi(com);
		if ("500".equals(tic_f.getState())) {
			throw new Exception("获取[" + tics.get(0).getProcess_point_desc() + "]工艺标准失败!" + tic_f.getMsgInfo());
		}
		if (Utils.isNotEmpty(tic_f)) {
			List<SlmOrdDesignMscTicItem> item_f = (List<SlmOrdDesignMscTicItem>) tic_f.getData();
			// 获取轧制入口厚度出口厚度的代码
			List<PbModelDb> code = getBase_Name("201001");
			for (SlmOrdDesignMscTicItem slmO : item_f) {
				// 入口厚度
				if (slmO.getCraft_param_code().equals(code.get(0).getText())) {
					if (slmO.getMin_value() == null && slmO.getMax_value() == null) {
						throw new Exception("未获取到工艺参数入口厚度,请重新质量设计!");
					}
					ithk_min_f = Double.valueOf(slmO.getMin_value() == null ? "0" : slmO.getMin_value());
					if (Utils.isNotEmpty(slmO.getMax_value())) {
						ithk_max_f = Double.valueOf(slmO.getMax_value());
					}
					break;
				}
			}

			if (ithk_max_f < thick) {
				throw new Exception(
						"第一道次轧制入口厚度范围[" + ithk_min_f + "," + ithk_max_f + "]不包含订单要求厚度[" + thick + "],请重新质量设计!");
			}
		}
	}

	/**
	 * 检验最后一个道次的出口厚度信息
	 * 
	 * @param tics
	 * @param thick
	 * @throws Exception
	 */
	public void checkLastProc(List<SlmOrdDesignMscTic> tics, double thick) throws Exception {

		double ithk_min_f = 0, ithk_max_f = 99;
		CommonPage<SlmOrdDesignMscTic> com = new CommonPage<SlmOrdDesignMscTic>();
		// 最后一个道次轧制
		com.setObject(tics.get(tics.size() - 1));
		ResultModel tic_f = this.getBean(QmsApiServiceImpl.class).getGongYi(com);
		if ("500".equals(tic_f.getState())) {
			throw new Exception("获取[" + tics.get(0).getProcess_point_desc() + "]工艺标准失败!" + tic_f.getMsgInfo());
		}
		List<SlmOrdDesignMscTicItem> item_f = (List<SlmOrdDesignMscTicItem>) tic_f.getData();
		if (Utils.isNotEmpty(tic_f)) {
			// 获取轧制入口厚度出口厚度的代码
			List<PbModelDb> code = getBase_Name("201001");
			for (SlmOrdDesignMscTicItem slmO : item_f) {
				// 入口厚度
				if (slmO.getCraft_param_code().equals(code.get(0).getText())) {
					if (slmO.getMin_value() == null && slmO.getMax_value() == null) {
						throw new Exception("未获取到工艺参数入口厚度,请重新质量设计!");
					}
					ithk_min_f = Double.valueOf(slmO.getMin_value() == null ? "0" : slmO.getMin_value());
					if (Utils.isNotEmpty(slmO.getMax_value())) {
						ithk_max_f = Double.valueOf(slmO.getMax_value());
					}
					break;
				}
			}

			if (ithk_max_f < thick || ithk_min_f > thick) {
				throw new Exception(
						"最后一道次轧制入口厚度[" + ithk_min_f + "," + ithk_max_f + "]不包含订单要求厚度[" + thick + "],请重新质量设计!");
			}
		}
	}

	/**
	 * 获取工艺参数
	 * 
	 * @param object_no_vt       虚拟物料号
	 * @param process_point_code 工序点代码 暂可不传
	 * @return
	 * @throws Exception
	 */
	public List<SlmOrdDesignMscTicItem> getPrc_Parms(String object_no_vt, String process_point_code) throws Exception {

		// 获取虚拟物料对应工序信息
		SlmOrdDesignMscPlSti sti = getPrc_Info_Of_Obvt(object_no_vt);
		if (Utils.isEmpty(sti)) {
			return null;
		}
		SlmOrdDesignMscTic tic = new SlmOrdDesignMscTic();
		BeanUtils.copyProperties(sti, tic);
		tic.setPline_code("C016");
		tic.setMachine_code("M0008");
		// 获取工艺参数
		CommonPage<SlmOrdDesignMscTic> com = new CommonPage<SlmOrdDesignMscTic>();
		com.setObject(tic);
		ResultModel tic_f = this.getBean(QmsApiServiceImpl.class).getGongYi(com);
		if ("500".equals(tic_f.getState())) {
			//20191001 不知道原因暂时被注释掉：
//			throw new Exception("获取[" + sti.getProcess_point_desc() + "]工艺标准失败!" + tic_f.getMsgInfo());
		}
		List<SlmOrdDesignMscTicItem> item = (List<SlmOrdDesignMscTicItem>) tic_f.getData();
		return item;

	}

	/**
	 * 获取质量设计信息(工序点最小单位)
	 * 
	 * @param sti
	 * @return
	 */
	public List<SlmOrdDesignMscPlSti> getQcmDesignInfo(SlmOrdDesignMscPlSti sti) {
		// 通过design_key 和全程产险码以及工序点代码获取工序序号
		List<SlmOrdDesignMscPlSti> listSti = this.getMapper(SlmOrdDesignMscPlStiMapper.class).findWithCondition(sti, "",
				" BACKLOG_SEQ ,PROCESS_POINT_SEQ", 0, 0);
		return listSti;
	}


	/**
	 * 获取基础数据
	 * 
	 * @param sort_code 父类编码 (201001 获取轧制工序工艺标准)
	 * @return
	 * @throws Exception
	 */
	public List<PbModelDb> getBase_Name(String sort_code) throws Exception {
		List<PbModelDb> lpm = new ArrayList<PbModelDb>();
		try {
			lpm = this.getMapper(PbModelDbMapper.class).findComBaseInfoCmdDb(sort_code);
		} catch (Exception ex) {
			throw new Exception("服务端异常，获取数据失败!");
		}
		return lpm;

	}
	
	
	/**
	 * 获取订单状态基础数据
	 * 
	 * @return
	 * @throws Exception
	 */
	public List<PbModelDb> getProd_Status() throws Exception {
		List<PbModelDb> lpm = new ArrayList<PbModelDb>();
		try {
			lpm = this.getMapper(PbModelDbMapper.class).getProd_Status();
		} catch (Exception ex) {
			throw new Exception("服务端异常，获取数据失败!");
		}
		return lpm;
		
	}

	/**
	 * 根据物料状态获取物料正在执行的工序 蠢方法暂时没想出更好的
	 * 
	 * @param status
	 * @return
	 */
	public String get_Prc_Code(String status) {
		String prc_code = "";
		// 工序点信息
		List<ComBaseInfo> infoi = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoi);
		// 分条
		if (status.contains("LW")) {
			prc_code = processpoint.slitting_code;
			// 开平
		} else if (status.contains("CL")) {
			prc_code = processpoint.cross_cutting_code;
			// 罩退
		} else if (status.contains("AN")) {
			prc_code = processpoint.anneal_code;
			// 平整
		} else if (status.contains("SR")) {
			prc_code = processpoint.smooth_code;
			// 轧制
		} else if (status.contains("RL")) {
			prc_code = processpoint.rolling_code;
			// 酸洗
		} else if (status.contains("PC")) {
			prc_code = processpoint.pickle_code;
		}
		return prc_code;
	}

	/**
	 * 获取工序路径
	 * 
	 * @param Whole_process_codes 工艺路径
	 * @param prc_code            当前工序
	 * @param repeat_index
	 * @return
	 */
	public String getPath(String Whole_process_codes, String prc_code, int repeat_index) {
		String temp = null;
		for (int i = 0; i < repeat_index; i++) {
			Whole_process_codes = StringUtils.substringAfter(Whole_process_codes, prc_code);
			//temp = StringUtils.substringAfter(Whole_process_codes, prc_code);
			temp = Whole_process_codes;
		}
		return temp;
	}

	/**
	 * 获取position
	 * 
	 * @param Whole_process_codes 工艺路径
	 * @param prc_code            当前工序
	 * @param repeat_index        重复次数
	 * @return
	 */
	public static int getPosition(String Whole_process_codes, String prc_code, int repeat_index) {
		int position = 0;
		for (int i = 0; i < repeat_index - 1; i++) {
			Whole_process_codes = Whole_process_codes.replaceFirst(prc_code, ",");
		}
		position = Whole_process_codes.indexOf(prc_code);
		return position;
	}

//	public static void main(String[] args) {
//		System.out.println(getPosition("EBEBE", "E", 3));
//	}

	/**
	 * 是否需要生成检验委托
	 * 
	 * @param object_no_vt 虚拟物料号
	 * @param process_code 当前工序代码 A/B/C/D/E
	 * @return res_int -1 不需要生成
	 * @throws Exception
	 */
	public int Judge_Contain_Qcm(String object_no_vt, String process_code) throws Exception {
		int res_int = -1;
		// 获取虚拟物料信息
		List<PlnMaterielDetail> lpmdc = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + object_no_vt + "' and nvl(invalid_flg,'0') = '0'", null, 0, 1);
		if (Utils.isEmpty(lpmdc)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt + "]信息");
		}
		// 获取生产订单信息
		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
				"prod_order_no = '" + lpmdc.get(0).getProd_order_no() + "'", "", 0, 1);
		if (Utils.isEmpty(ppo)) {
			throw new Exception("未找到虚拟物料[" + object_no_vt + "]对应的订单信息");
		}
		// 通过design_key 和全程产险码以及工序点代码获取工序序号
		SlmOrdDesignMscPlSti sti = new SlmOrdDesignMscPlSti();
		sti.setDesign_key(ppo.get(0).getDesign_key());
		sti.setMsc_pline(ppo.get(0).getMsc_pline());
		sti.setProcess_code(process_code);
		List<SlmOrdDesignMscPlSti> listSti = this.getMapper(PlnProdorderExtinfoMapper.class).getQcmPrcInfo(sti);
		if (Utils.isEmpty(listSti))
			return res_int;
		SlmOrdDesignMscPlSti tmp = listSti.get(0);
		if (Utils.isEmpty(lpmdc.get(0).getProc_repeat_index())) {
			// 获取母卷虚拟物料信息
			List<PlnMaterielDetail> pmd_M = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					" object_no_vt = '" + lpmdc.get(0).getMat_object_no_vt() + "' and nvl(invalid_flg,0) <> 1 ", "", 0,
					1);
			if (Utils.isEmpty(pmd_M) || listSti.size() < pmd_M.get(0).getProc_repeat_index()) {
				return res_int;
			} else if (listSti.size() >= pmd_M.get(0).getProc_repeat_index()) {
				tmp = listSti.get(pmd_M.get(0).getProc_repeat_index() - 1);
			}
		} else if (listSti.size() >= lpmdc.get(0).getProc_repeat_index() && lpmdc.get(0).getProc_repeat_index() > 1) {
			tmp = listSti.get(lpmdc.get(0).getProc_repeat_index() - 1);
		}
		// 有结果说明有材质/成分类工序点
		List<SlmOrdDesignMscPlSti> list = this.getMapper(SlmOrdDesignMscPlStiMapper.class).findWithCondition(null,
				" design_key = '" + ppo.get(0).getDesign_key() + "'  AND MSC_PLINE = '" + ppo.get(0).getMsc_pline()
						+ "' and process_code = '" + process_code + "' and backlog_seq = '" + tmp.getBacklog_seq()
						+ "' and PROCESS_POINT_TYPE in ('403201','403202')",
				"  BACKLOG_SEQ, PROCESS_POINT_SEQ", 0, 0);
		if (Utils.isNotEmpty(list)) {
			res_int = tmp.getBacklog_seq().intValue();
		}
		return res_int;
	}

	/**
	 * 销售订单能否拆分
	 * 
	 * @param order_no 销售订单主键
	 * @param wgt      拆分重量 默认0拆分整个订单, >0 判断对应量能否拆分
	 * @return flag ture
	 */
	public boolean cib_Split(String order_no, double wgt) {
		return true;
	}

//	public boolean cib_Split(String order_no, double wgt) {
//		// 工序信息
//		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
//				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
//		ProcessPoint processpoint = new ProcessPoint(infoI);
//		double dsn = 0;
//		boolean flag = false;
//		// 判断生产订单是否已完全挂单
//		List<PlnProdorder> ppo = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
//				" ord_pk = '" + order_no + "'", null, 0, 1);
//		// 获取生产订单进程信息
//		List<PlnProdorderStatistic> pps = this.getMapper(PlnProdorderStatisticMapper.class).findWithCondition(null,
//				" prod_order_no = '" + ppo.get(0).getProd_order_no() + "'", null, 0, 1);
//		if (ppo.get(0).getWhole_process_codes().contains(processpoint.slitting_code)) {
//			dsn = pps.get(0).getLw_dsn();
//		} else if (ppo.get(0).getWhole_process_codes().contains(processpoint.cross_cutting_code)) {
//			dsn = pps.get(0).getCl_dsn();
//		} else if (ppo.get(0).getWhole_process_codes().contains(processpoint.anneal_code)) {
//			dsn = pps.get(0).getAn_dsn();
//		} else if (ppo.get(0).getWhole_process_codes().contains(processpoint.smooth_code)) {
//			dsn = pps.get(0).getSr_dsn();
//		} else if (ppo.get(0).getWhole_process_codes().contains(processpoint.rolling_code)) {
//			dsn = pps.get(0).getRl_dsn();
//		} else if (ppo.get(0).getWhole_process_codes().contains(processpoint.pickle_code)) {
//			dsn = pps.get(0).getPc_dsn();
//		}
//		if (wgt == 0) {
//			if (ppo.get(0).getDelivery_error_min() < dsn) {
//				// 判断是不是都已经生产完成
//				List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
//						"order_no = '" + ppo.get(0).getOrder_no()
//								+ "' and next_process_code is null and object_no is null",
//						null, 0, 0);
//				if (Utils.isEmpty(pmd)) {
//					flag = true;
//				}
//			}
//		} else if (wgt > 0) {
//			if (dsn >= wgt*1000) {
//				double finish_db = 0;
//				// 判断完成的量是否 > wgt
//				List<PlnMaterielDetail> pmd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
//						"order_no = '" + ppo.get(0).getOrder_no()
//								+ "' and next_process_code is null and object_no is not null",
//						null, 0, 0);
//				for (PlnMaterielDetail pln : pmd) {
//					finish_db += pln.getSingle_weight();
//				}
//				if (finish_db >= wgt*1000) {
//					flag = true;
//				}
//			}
//		}
//		return flag;
//	}

	/**
	 * 获取计划状态
	 * 
	 * @param prefix 分条LW/开平CL/罩退AN/平整SR/轧制RL/酸洗PC
	 * @return
	 */
	public List<PbModelDb> getPlanStatus(String prefix) {
		List<PbModelDb> rst = new ArrayList<PbModelDb>();
		PbModelDb pb = new PbModelDb();
		pb.setId("0");
		pb.setText("全部");
		rst.add(pb);
		PbModelDb pb0 = new PbModelDb();
		pb0.setId("5B" + prefix + "01");
		pb0.setText("已编制计划");
		rst.add(pb0);
		PbModelDb pb1 = new PbModelDb();
		pb1.setId("5B" + prefix + "02");
		pb1.setText("计划已下发");
		rst.add(pb1);
		PbModelDb pb2 = new PbModelDb();
		pb2.setId("5B" + prefix + "03");
		pb2.setText("开始作业");
		rst.add(pb2);
		PbModelDb pb3 = new PbModelDb();
		if("AN".equals(prefix)) {
			pb3.setId("5B" + prefix + "80");
		}else {
			pb3.setId("5B" + prefix + "10");
		}
		pb3.setText("已完成计划");
		rst.add(pb3);
		return rst;
	}
	
	
	
	/**
	 * 获取工艺参数
	 * 
	 * @param object_no_vt       虚拟物料号
	 * @param machine_code       机台代码 暂可不传
	 * @return
	 * @throws Exception
	 */
	public List<SlmOrdDesignMscTicItem> getPrc_Params(String object_no_vt, String machine_code) throws Exception {

		// 获取虚拟物料对应工序信息
		SlmOrdDesignMscPlSti sti = getPrc_Info_Of_Obvt(object_no_vt);
		if (Utils.isEmpty(sti)) {
			return null;
		}
		SlmOrdDesignMscTic tic = new SlmOrdDesignMscTic();
		SlmOrdDesignMscPlGxPrl prl = new SlmOrdDesignMscPlGxPrl();
		BeanUtils.copyProperties(sti, prl);
		BeanUtils.copyProperties(sti, tic);
		// 获取产线
		List<SlmOrdDesignMscPlGxPrl> listPrl =this.getMapper(SlmOrdDesignMscPlGxPrlMapper.class).find(prl, 0, 0);
		if(Utils.isNotEmpty(listPrl)) {
			tic.setPline_code(listPrl.get(0).getPline_code());
		}
//		tic.setMachine_code(machine_code);
		// 获取工艺参数
		CommonPage<SlmOrdDesignMscTic> com = new CommonPage<SlmOrdDesignMscTic>();
		com.setObject(tic);
		ResultModel tic_f = this.getBean(QmsApiServiceImpl.class).getGongYi(com);
		if ("500".equals(tic_f.getState())) {
			// 20191001 不知道原因暂时注释掉：
//			throw new Exception("获取[" + sti.getProcess_point_desc() + "]工艺标准失败!" + tic_f.getMsgInfo());
		}
		List<SlmOrdDesignMscTicItem> item = (List<SlmOrdDesignMscTicItem>) tic_f.getData();
		return item;

	}

}
