/***文档注释***********************************************
 * 作者               :                   易鑫
 * 创建日期      :                   2017.11.22
 * 描述               :        			作业计划明细数据（原料卷切割计划）
 * 注意事项      :                   无
 * 遗留BUG :                   无
 * 修改日期      :                   
 * 修改人员      :                   
 * 修改内容      :                   
***********************************************************/

package market.Mes.Lengthwise.Plan.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import market.Api.Mes.impl.MesApiDesignInfoImpl;
import market.Api.Mes.impl.ProcessPoint;
import market.Api.Mes.impl.Utils;
import market.Api.Mes.service.MesApiDesignInfoService;
import market.Api.Qms.impl.QmsApiServiceImpl;
import market.Com.mapper.ComBaseInfoMapper;
import market.Com.vo.ComBaseInfo;
import market.Com.vo.CommonPage;
import market.Com.vo.ResultModel;
import market.Lms.Warehouse.mapper.YdmProductDetailMapper;
import market.Lms.Warehouse.vo.YdmProductDetail;
import market.Mes.Cuttolength.Design.mapper.PlnCuttolengthDsnMainMapper;
import market.Mes.Cuttolength.Design.mapper.PlnCuttolengthDsnMultinfoMapper;
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.service.PlnCuttolengthPlanService;
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.Plan.mapper.PlnLengthwisePlanDetailMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnMatReplaceLogMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnMaterielDetailMapper;
import market.Mes.Lengthwise.Plan.service.PlnLengthwisePlanService;
import market.Mes.Lengthwise.Plan.service.PlnMaterielDetailService;
import market.Mes.Lengthwise.Plan.vo.PlnLengthwisePlanDetail;
import market.Mes.Lengthwise.Plan.vo.PlnMatReplaceLog;
import market.Mes.Lengthwise.Plan.vo.PlnMaterielDetail;
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.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.service.PlnPickleDsnMultinfoService;
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.service.PlnRollingDsnMultinfoService;
import market.Mes.Rolling.Design.vo.PlnRollingDsnMain;
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.service.PlnSkinrollingDsnMultinfoService;
import market.Mes.Tpm.Design.vo.PlnSkinrollingDsnMain;
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.service.PlnAnnealDsnMultinfoService;
import market.Mes.anneal.Design.vo.PlnAnnealDsnMain;
import market.Mes.anneal.mapper.PlnAnnealPlanDetailMapper;
import market.Mes.anneal.vo.PlnAnnealPlanDetail;
import market.Slm.FundManagement.service.SlmFundFirstDetailService;

import org.apache.commons.lang.StringUtils;
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 = "PlnMaterielDetailService")
public class PlnMaterielDetailServiceImpl extends BaseServiceImpl<PlnMaterielDetail, Object>
		implements PlnMaterielDetailService {

	/**
	 * 分条作业计划明细数据查询
	 */
	public ResultModel doQueryWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			PlnMaterielDetail mcsm = oci.getObject();
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQuery(mcsm));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}

	/**
	 * 点击某虚拟母卷的展开+按钮，展示【虚拟母卷号】对应的虚拟子卷信息
	 */
	public ResultModel doQueryInfoWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQueryInfo(oci.getObject()));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}

	/**
	 * 横剪计划编制查询子卷信息 点击某虚拟母卷的展开+按钮，展示【虚拟母卷号】对应的虚拟子卷信息
	 */
	public ResultModel doQueryCl_Sub_InfoWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQueryCl_Sub_InfoWeb(oci.getObject()));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}

	/**
	 * 罩退计划编制查询子卷信息 点击某虚拟母卷的展开+按钮，展示【虚拟母卷号】对应的虚拟子卷信息
	 */
	public ResultModel doQueryAn_Sub_InfoWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQueryAn_Sub_InfoWeb(oci.getObject()));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}

	/**
	 * 平整计划编制查询子卷信息 点击某虚拟母卷的展开+按钮，展示【虚拟母卷号】对应的虚拟子卷信息
	 */
	public ResultModel doQuerySr_Sub_InfoWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQuerySr_Sub_InfoWeb(oci.getObject()));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}
	
	/**
	 * 轧制计划编制查询子卷信息 点击某虚拟母卷的展开+按钮，展示【虚拟母卷号】对应的虚拟子卷信息
	 */
	public ResultModel doQueryRl_Sub_InfoWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQueryRl_Sub_InfoWeb(oci.getObject()));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}
	
	/**
	 * 酸洗计划编制查询子卷信息 点击某虚拟母卷的展开+按钮，展示【虚拟母卷号】对应的虚拟子卷信息
	 */
	public ResultModel doQueryPC_Sub_InfoWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQueryPC_Sub_InfoWeb(oci.getObject()));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}

	/**
	 * 分条设计查询已设计的原料
	 */
	public ResultModel doQueryDsnWeb(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			if (oci.getObject() == null) {
				rm.setState("200");
				rm.setMsgInfo("请传入查询参数");
				return rm;
			}
			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doQueryDsn(oci.getObject()));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}

	/**
	 * 可充当虚拟卷
	 */
	public ResultModel doActQuery(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		try {
			PlnMaterielDetail sum = oci.getObject();
			String sWhere = "";
			// 设计时间
			sWhere += " and t2.create_time between to_date('" + oci.getStartTime()
					+ "','yyyy-MM-dd HH24:mi:ss') and to_date('" + oci.getEndTime() + "','yyyy-MM-dd HH24:mi:ss') ";
			String sWhere2 = "";
			if (sum != null) {
				if (oci.getMemo1() != null && !"".equals(oci.getMemo1())) {
					sWhere2 += " and t.diameter_out>=" + Double.parseDouble(oci.getMemo1());
				}
				if (oci.getMemo2() != null && !"".equals(oci.getMemo1())) {
					sWhere2 += " and t.diameter_out<=" + Double.parseDouble(oci.getMemo2());
				}

				if (sum.getOrder_no() != null && !"".equals(sum.getOrder_no().trim())) {
					sWhere2 += " and t.order_no like '%" + sum.getOrder_no().trim() + "%' ";
				}
				if (sum.getProd_order_no() != null && !"".equals(sum.getProd_order_no().trim())) {
					sWhere2 += " and t.prod_order_no like '%" + sum.getProd_order_no().trim() + "%' ";
				}
				if (sum.getLw_plan_no() != null && !"".equals(sum.getLw_plan_no().trim())) {
					sWhere2 += " and t.lw_plan_no like '%" + sum.getLw_plan_no().trim() + "%' ";
				}

				if (!"".equals(sWhere2)) {
					sWhere += " and exists (select 1 from pln_lengthwise_dsn_multinfo t3 where t.lw_design_no = t3.lw_design_no "
							+ sWhere2 + " ) ";
				}
			}

			rm.setData(this.getMapper(PlnMaterielDetailMapper.class).doActQuery(sum, sWhere));
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}

	/**
	 * 分条成品充当 memo1实物卷号 memo2 OBJECT_TYPE 卷类型？
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doFinshedProductAct(CommonPage<PlnProdorder> oci) {
		ResultModel rm = new ResultModel();
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		PlnProdorder pmd = oci.getObject();
		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(pmd.getProd_order_no());
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 0);
		if (lpp == null || lpp.size() == 0) {
			rm.setState("500");
			rm.setMsgInfo("生产订单[" + pp.getProd_order_no() + "]信息不存在");
			return rm;
		}
		// 对传入的实物卷，查询库存信息[物流接口],若不存在信息，则报错“库存中无实物[xxx]信息”。
		YdmProductDetail ypd = new YdmProductDetail();
		ypd.setCoilno(oci.getMemo1());// 实物卷号
		List<YdmProductDetail> lypd = this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
		if (lypd == null || lypd.size() == 0) {
			rm.setState("500");
			rm.setMsgInfo("库存中无实物[" + oci.getMemo1() + "]信息");
			return rm;
		}

		// 判断实物，和订单的厚、宽、长、内径、外径、牌号、交货状态是否匹配
		if (!lpp.get(0).getThick().equals(lypd.get(0).getThick())) {
			rm.setState("500");
			rm.setMsgInfo("实物与订单的厚不匹配，不能充当！");
			return rm;
		}
		if (lpp.get(0).getWidth() > lypd.get(0).getWidth()) {
			rm.setState("500");
			rm.setMsgInfo("实物宽度不能小于要求的宽，不能充当！");
			return rm;
		}

		/*
		 * if(!lpp.get(0).getDiameter_inn().equals(lypd.get(0).getDiameter_inn())){
		 * rm.setState("500"); rm.setMsgInfo("实物与订单的内径不匹配，不能充当！"); return rm; }
		 * if(!lpp.get(0).getDiameter_out().equals(lypd.get(0).getDiameter_out())){
		 * rm.setState("500"); rm.setMsgInfo("实物与订单的外径不匹配，不能充当！"); return rm; }
		 */

		if (!lpp.get(0).getSteel_code().equals(lypd.get(0).getSteelcode())) {
			rm.setState("500");
			rm.setMsgInfo("实物与订单的牌号不匹配，不能充当！");
			return rm;
		}

		// ***************调用质量接口，传入 订单号和实物卷号，判断其他要求是否符合，不符合则报错退出
		// **************************

		// 生产订单进程表[PLN_PRODORDER_STATISTIC]
		Double db = lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight());
		PlnProdorderStatistic pps = new PlnProdorderStatistic();
		pps.setProd_order_no(pmd.getProd_order_no());
		pps.setReplaced(lypd.get(0).getFactweight());
		pps.setReplaced_cnt(1);
		pps.setUnscheduled(db);
		pps.setUnscheduled_cnt(-1);
		pps.setReplaced_times(1);

		// 订单进程表[PLN_ORDER_STATISTIC]
		PlnOrderStatistic pos = new PlnOrderStatistic();
		pos.setOrder_no(lpp.get(0).getOrder_no());
		pos.setReplaced(lypd.get(0).getFactweight());
		pos.setReplaced_cnt(1);
		pos.setUnscheduled(db);
		pos.setUnscheduled_cnt(-1);
		pos.setReplaced_times(1);
		// 最后一道为分条工序 欠分条设计_成品量[LW_UNDSN]-=实物重量；欠分条设计_成品数[LW_UNDSN_CNT]-=1
		if (processpoint.slitting_code
				.equals(this.getBean(QmsApiServiceImpl.class).GetWrkPlanCode(lpp.get(0).getOrder_no()))) {
			pps.setLw_undsn(db);
			pps.setLw_undsn_cnt(-1);

			pos.setLw_undsn(db);
			pos.setLw_undsn_cnt(-1);
		}

		this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
		this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);

		lypd.get(0).setProdorderno(lpp.get(0).getProd_order_no());
		lypd.get(0).setOrderno(lpp.get(0).getOrder_no());

		lypd.get(0).setCustomer_no(lpp.get(0).getCustomer_no());
		lypd.get(0).setCustomer_nm(lpp.get(0).getCustomer_name());
		lypd.get(0).setReceiv_nm(lpp.get(0).getReciver_unit_name());
		lypd.get(0).setReceiv_no(lpp.get(0).getReciver_unit_no());
		// 修改库存表
		this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(lypd.get(0));

		rm.setState("200");
		;
		return rm;
	}

	/**
	 * 分条原料充当 memo1实物卷
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doMaterialAct(CommonPage<PlnMaterielDetail> oci) {
		ResultModel rm = new ResultModel();
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		PlnMaterielDetail pmd = oci.getObject();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		PlnMaterielDetail pp = new PlnMaterielDetail();
		pp.setObject_no_vt(pmd.getObject_no_vt());
		List<PlnMaterielDetail> lpp = this.getMapper(PlnMaterielDetailMapper.class).find(pp, 0, 0);
		if (lpp == null || lpp.size() == 0) {
			rm.setState("500");
			rm.setMsgInfo("虚拟物料[" + pp.getObject_no_vt() + "]信息不存在");
			return rm;
		}
		// 对传入的实物卷，查询库存信息[物流接口],若不存在信息，则报错“库存中无实物[xxx]信息”。
		YdmProductDetail ypd = new YdmProductDetail();
		ypd.setCoilno(oci.getMemo1());// 实物卷号
		List<YdmProductDetail> lypd = this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
		if (lypd == null || lypd.size() == 0) {
			rm.setState("500");
			rm.setMsgInfo("库存中无实物[" + oci.getMemo1() + "]信息");
			return rm;
		}

		// 判断实物，和订单的厚、宽、长、内径、外径、牌号、交货状态是否匹配
		if (!lpp.get(0).getThick().equals(lypd.get(0).getThick())) {
			rm.setState("500");
			rm.setMsgInfo("实物与虚拟物料的厚不匹配，不能充当！");
			return rm;
		}
		if (lpp.get(0).getWidth() > lypd.get(0).getWidth()) {
			rm.setState("500");
			rm.setMsgInfo("实物宽度不能小于要求的宽，不能充当！");
			return rm;
		}

		/*
		 * if(!lpp.get(0).getDiameter_inn().equals(lypd.get(0).getDiameter_inn())){
		 * rm.setState("500"); rm.setMsgInfo("实物与虚拟物料的内径不匹配，不能充当！"); return rm; }
		 * if(!lpp.get(0).getDiameter_out().equals(lypd.get(0).getDiameter_out())){
		 * rm.setState("500"); rm.setMsgInfo("实物与虚拟物料的外径不匹配，不能充当！"); return rm; }
		 */
		if (!lpp.get(0).getSteel_code().equals(lypd.get(0).getSteelcode())) {
			rm.setState("500");
			rm.setMsgInfo("实物与虚拟物料的牌号不匹配，不能充当！");
			return rm;
		}

		// ***************调用质量接口，传入 订单号和实物卷号，判断其他要求是否符合，不符合则报错退出
		// **************************

		if (lpp.get(0).getObject_no() != null && !"".equals(lpp.get(0).getObject_no())) {
			rm.setState("500");
			rm.setMsgInfo("虚拟物料[" + lpp.get(0).getObject_no_vt() + "]已经挂载实物[" + lpp.get(0).getObject_no() + "]，不能充当！");
			return rm;
		}

		// 判断是否分条工序成品虚拟物料
		if (processpoint.slitting_code.equals(lpp.get(0).getPrev_process_code())) {
			if (!"1".equals(lpp.get(0).getIs_finished())) {
				rm.setState("500");
				rm.setMsgInfo("虚拟物料[" + lpp.get(0).getObject_no_vt() + "]已作坯料设计，且生产尚未结束，不能充当！");
				return rm;
			}
			// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
			PlnProdorderStatistic pps = new PlnProdorderStatistic();
			pps.setProd_order_no(lpp.get(0).getProd_order_no());
			pps.setReplaced(lypd.get(0).getFactweight());
			pps.setReplaced_cnt(1);
			pps.setUnscheduled(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
			pps.setUnscheduled_cnt(-1);
			pps.setReplaced_times(1);

			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(lpp.get(0).getOrder_no());
			pos.setReplaced(lypd.get(0).getFactweight());
			pos.setReplaced_cnt(1);
			pos.setUnscheduled(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
			pos.setUnscheduled_cnt(-1);
			pos.setReplaced_times(1);

			this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);

		} else if (processpoint.slitting_code.equals(lpp.get(0).getNext_dsn_process_code())) {
			// 判断是否分条工序原料虚拟物料
			if ("1".equals(lpp.get(0).getNeed_extopt()) && !"1".equals(lpp.get(0).getIs_finished())) {
				rm.setState("500");
				rm.setMsgInfo("虚拟物料[" + lpp.get(0).getObject_no_vt() + "]已作坯料设计，且生产尚未结束，不能充当！");
				return rm;
			}
			if (lpp.get(0).getLw_plan_no() != null && !"".equals(lpp.get(0).getLw_plan_no())) {
				// 根据 （LW_PLAN_NO 和 虚拟物料号），找到对应的 分条计划明细【PLN_LENGTHWISE_PLAN_DETAIL】记录
				PlnLengthwisePlanDetail plpd = new PlnLengthwisePlanDetail();
				plpd.setLw_plan_no(lpp.get(0).getLw_plan_no());
				plpd.setObject_no_vt(lpp.get(0).getObject_no_vt());
				List<PlnLengthwisePlanDetail> lplpd = this.getMapper(PlnLengthwisePlanDetailMapper.class).find(plpd, 0,
						1);
				if (lplpd != null && lplpd.size() > 0) {
					PlnLengthwisePlanDetail plpdu = new PlnLengthwisePlanDetail();
					plpdu.setSerial_no(lplpd.get(0).getSerial_no());
					plpdu.setObject_no(oci.getMemo1());
					this.getMapper(PlnLengthwisePlanDetailMapper.class).update(plpdu);
				}

			}

			// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
			PlnProdorderStatistic pps = new PlnProdorderStatistic();
			pps.setProd_order_no(lpp.get(0).getProd_order_no());
			pps.setMat_lw_replaced(lypd.get(0).getFactweight());
			pps.setMat_lw_replaced_cnt(1);
			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

			// 修改订单进程表[PLN_ORDER_STATISTIC]
			PlnOrderStatistic pos = new PlnOrderStatistic();
			pos.setOrder_no(lpp.get(0).getOrder_no());
			pos.setMat_lw_replaced(lypd.get(0).getFactweight());
			pos.setMat_lw_replaced_cnt(1);
			this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);

		} else {
			rm.setState("500");
			rm.setMsgInfo("虚拟物料不是分条工序的原料或成品物料，无法充当！\n (请刷新检查分条坯料设计是否有变化)");
			return rm;
		}

		// 修改库存表 虚拟物料 关联 物料号
		lypd.get(0).setProdorderno(lpp.get(0).getProd_order_no());
		lypd.get(0).setOrderno(lpp.get(0).getOrder_no());
		lypd.get(0).setObject_no_vt(lpp.get(0).getObject_no_vt());

		PlnProdorder ppq = new PlnProdorder();
		pp.setProd_order_no(lpp.get(0).getProd_order_no());
		List<PlnProdorder> lp = this.getMapper(PlnProdorderMapper.class).find(ppq, 0, 1);
		if (lp != null && lp.size() > 0) {
			lypd.get(0).setCustomer_no(lp.get(0).getCustomer_no());
			lypd.get(0).setCustomer_nm(lp.get(0).getCustomer_name());
			lypd.get(0).setReceiv_nm(lp.get(0).getReciver_unit_name());
			lypd.get(0).setReceiv_no(lp.get(0).getReciver_unit_no());
		}

		this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(lypd.get(0));

		// 修改虚拟物料表
		PlnMaterielDetail pmdu = new PlnMaterielDetail();
		pmdu.setSerial_no(lpp.get(0).getSerial_no());
		pmdu.setReplaced_times((lpp.get(0).getReplaced_times() == null ? 0 : lpp.get(0).getReplaced_times()) + 1);
		pmdu.setObject_no(oci.getMemo1());
		pmdu.setIs_replaced("1");
		this.getMapper(PlnMaterielDetailMapper.class).update(pmdu);

		// 物料充当脱单履历
		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();
		mmrl.setLw_plan_no(lpp.get(0).getLw_plan_no());
		mmrl.setLw_design_no(lpp.get(0).getLw_design_no());
		mmrl.setSerial_no(iNo++);
		mmrl.setObject_no(oci.getMemo1());
		mmrl.setPline_code(lpp.get(0).getPline_code());
		mmrl.setObject_type(oci.getMemo2());
		mmrl.setOpt_type("1");
		mmrl.setStatus(lypd.get(0).getState());
		mmrl.setObject_no_vt(lpp.get(0).getObject_no_vt());
		mmrl.setOrder_no(lpp.get(0).getOrder_no());
		mmrl.setProd_order_no(lpp.get(0).getProd_order_no());
		mmrl.setLw_design_no(lpp.get(0).getLw_design_no());
		mmrl.setCl_design_no(lpp.get(0).getCl_design_no());
		mmrl.setRl_design_no(lpp.get(0).getRl_design_no());
		mmrl.setLw_plan_no(lpp.get(0).getLw_plan_no());
		mmrl.setCl_plan_no(lpp.get(0).getCl_plan_no());
		mmrl.setRl_plan_no(lpp.get(0).getRl_plan_no());
		mmrl.setCreate_man_name(userName);
		mmrl.setCreate_time(new Date());
		// this.getMapper(MilMatReplaceLogMapper.class).insert(mmrl);

		rm.setState("200");
		;
		return rm;
	}

	/**
	 * 脱单接口(五合一) 传入参数(虚拟物料号、实物卷号、备注、操作人) 没有经过生产的直接删掉,子卷也删掉
	 * 
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doMaterialReplace(CommonPage<PlnMaterielDetail> oci) throws Exception {
		ResultModel rm = new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		List<PlnMaterielDetail> lpm = oci.getObjectList();
		
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		// 物料充当脱单履历
		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;
		}

		int num = 0 ;
		for (PlnMaterielDetail pm : lpm) {
			YdmProductDetail ypd  = this.getMapper(YdmProductDetailMapper.class).findById(pm.getObject_no());
			// 不存在物料信息
			if (ypd == null) {
				rm.setState("500");
				rm.setMsgInfo("物料[" + pm.getObject_no() + "]库存信息不存在！");
				return rm;
			}
			
			
			// 卷号是唯一的值
			// 实际物料 不是在库状态
			if (!"0".equals(ypd.getState())) {
				rm.setState("500");
				rm.setMsgInfo("物料[" + ypd.getCoilno() + "]不是[在库]状态，不能脱单！");
				return rm;
			}
			//20191114脱单时判断是否有综合判定，如果没有综合判定，不允许脱单
			if (StringUtils.isEmpty(ypd.getJudgeresult())) {
				rm.setState("500");
				rm.setMsgInfo("物料[" + ypd.getCoilno() + "]没有综合判定结果，不能脱单！");
				return rm;
			}
			
			// 卷必须没有经过任何计划编制：2023011301 pm.getObject_no()
			List<PlnPicklePlanDetail> pdList = this.getMapper(PlnPicklePlanDetailMapper.class).findWithCondition(null, " OBJECT_NO = '"+pm.getObject_no()+"'", null, 0, 1);
			List<PlnLengthwisePlanDetail> pleList = this.getMapper(PlnLengthwisePlanDetailMapper.class).findWithCondition(null, " OBJECT_NO = '"+pm.getObject_no()+"'", null, 0, 1);
			List<PlnAnnealPlanDetail> plaList = this.getMapper(PlnAnnealPlanDetailMapper.class).findWithCondition(null, " OBJECT_NO = '"+pm.getObject_no()+"'", null, 0, 1);
			List<PlnSkinrollingPlanDetail> plsList = this.getMapper(PlnSkinrollingPlanDetailMapper.class).findWithCondition(null, " OBJECT_NO = '"+pm.getObject_no()+"'", null, 0, 1);
			List<PlnRollingPlanDetail> plrList = this.getMapper(PlnRollingPlanDetailMapper.class).findWithCondition(null, " OBJECT_NO = '"+pm.getObject_no()+"'", null, 0, 1);
			
			if (pdList.size() > 0 || pleList.size() > 0 || plaList.size() > 0 || plsList.size() > 0 || plrList.size() > 0) {
				throw new Exception("卷号" + pm.getObject_no() + "已经计划编制，不允许脱单！");
			}
			// end
			
			this.getBean(SlmFundFirstDetailService.class).ycjsPYdd(ypd.getCoilno(), false); // 一次结算后抛异动点
			
			// 物料充当脱单履历表
			PlnMatReplaceLog mmrl = new PlnMatReplaceLog();
			mmrl.setSerial_no(iNo++);
			mmrl.setOpt_type("0");
			mmrl.setStatus(ypd.getState());
			mmrl.setCreate_man_name(userName);
			mmrl.setCreate_time(new Date());
			mmrl.setObject_no(pm.getObject_no());
			mmrl.setRemark(pm.getRemark());
			mmrl.setMemo(oci.getMemo1());//脱单备注
			if (pm.getObject_no_vt() == null || "".equals(pm.getObject_no_vt().trim())) {
				// 虚拟物料号不存在，则调用逻辑1
				// 对物料对应的生产订单，查询生产订单表[PLN_PRODORDER],若不存在信息，则报错“生产订单[xxx]信息不存在”。
				PlnProdorder pp = new PlnProdorder();
				pp.setOrder_no(ypd.getOrderno());
				List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 0);
				if (lpp == null || lpp.size() == 0) {
					// 生产订单[xxx]信息不存在
					rm.setState("500");
					rm.setMsgInfo("生产订单[" + pp.getOrder_no() + "]信息不存在");
					return rm;
				}
				
				// 验证生产订单状态是否为订单保留：20230908刘侣
				if ("0PAA60".equals(lpp.get(0).getStatus())) {
					rm.setState("500");
					rm.setMsgInfo("生产订单["+lpp.get(0).getProd_order_no()+"]为 ‘订单保留’ 状态，不允许脱单");
					return rm;
				}
				if ("0PAA70".equals(lpp.get(0).getStatus())) {
					rm.setState("500");
					rm.setMsgInfo("生产订单["+lpp.get(0).getProd_order_no()+"]为 ‘订单作废’ 状态，不允许脱单");
					return rm;
				}
				
				// 验证生产订单是否锁定
				boolean flag = this.getBean(MesApiDesignInfoImpl.class).pOrdIsLocked(ypd.getProdorderno());
				if (flag) {
					throw new Exception("生产订单已经锁定[订单变更中],不允许脱单!");
				}

				// 最后一道工序为分条工序
				// if(processpoint.slitting_code.equals(this.getBean(QmsApiServiceImpl.class).GetWrkPlanCode(pp.getOrder_no()))){
				// 获得生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(lpp.get(0).getProd_order_no());
				pps.setReplaced(ypd.getFactweight() == null ? null : (-ypd.getFactweight()));
				pps.setReplaced_cnt(-1);
				pps.setUnscheduled(ypd.getFactweight());
				// pps.setUnscheduled_cnt(1);
				// pps.setReplaced_times(-1);
				pps.setDivorced_times(1);

				// 欠分条设计_成品量[LW_UNDSN]+=实物重量；欠分条设计_成品数[LW_UNDSN_CNT]+=1
				// pps.setLw_undsn(lypd.get(0).getFactweight());
				// pps.setLw_undsn_cnt(1);

				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

				// 修改订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(lpp.get(0).getOrder_no());

				pos.setReplaced(ypd.getFactweight() == null ? null : (-ypd.getFactweight()));
				pos.setReplaced_cnt(-1);
				pos.setUnscheduled(ypd.getFactweight());
				// pos.setUnscheduled_cnt(1);
				// pos.setReplaced_times(-1);
				pos.setDivorced_times(1);
				// 欠分条设计_成品量[LW_UNDSN]+=实物重量；欠分条设计_成品数[LW_UNDSN_CNT]+=1
				// pos.setLw_undsn(lypd.get(0).getFactweight());
				// pos.setLw_undsn_cnt(1);

				this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);

				// }

				// 将 虚拟物料表 的 OBJECT_NO 物料(卷/带/板)号 设置为NULL
				List<PlnMaterielDetail> pmds = this.getMapper(PlnMaterielDetailMapper.class)
						.findWithCondition(null, " object_no = '"+pm.getObject_no()+"' and nvl(invalid_flg,0) = 0 ", null, 0, 1);
				if (Utils.isNotEmpty(pmds)) {
					pmds.get(0).setObject_no(null);
					pmds.get(0).setDivorced_times(
							(pmds.get(0).getDivorced_times() == null ? 0 : pmds.get(0).getDivorced_times()) + 1);
					this.getMapper(PlnMaterielDetailMapper.class).doMaterialReplaceUpdate(pmds.get(0));
					
				}

				// 调用物流接口，将 实物物料 对应的虚拟物料号 置位NULL
				this.getMapper(YdmProductDetailMapper.class).doMaterialReplaceUpdate(ypd);

				mmrl.setOrder_no(lpp.get(0).getOrder_no());
				mmrl.setProd_order_no(ypd.getProdorderno());

			} else {
				// 虚拟物料号存在，则调用逻辑2
				// 对物料对应的虚拟物料号，查询虚拟物料表[PLN_MATERIEL_DETAIL]根据虚拟物料号查询物料信息
				PlnMaterielDetail pmd = new PlnMaterielDetail();
				pmd.setObject_no_vt(pm.getObject_no_vt());
				List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmd, 0, 0);

				// 查询生产订单信息
				List<PlnProdorder> pln = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
						" prod_order_no = '" + lpmd.get(0).getProd_order_no() + "'", null, 0, 1);
				if (Utils.isEmpty(pln)) {
					rm.setState("500");
					rm.setMsgInfo("生产订单[" + pm.getProd_order_no() + "]信息不存在!");
					return rm;
				}

				// 验证生产订单是否锁定
				boolean flag = this.getBean(MesApiDesignInfoImpl.class).pOrdIsLocked(ypd.getProdorderno());
				if (flag) {
					throw new Exception("生产订单已经锁定[订单变更中],不允许脱单!");
				}

				// 厂内合同并且已生生产完成--脱单,修改库存信息
				boolean flag_Ct = this.getBean(MesApiDesignInfoImpl.class).getContractType(lpmd.get(0).getProd_order_no());
				boolean flag_Mf = this.getBean(MesApiDesignInfoImpl.class).matIsFinish(pm.getObject_no());
				if (flag_Mf && flag_Ct) {
					this.getMapper(YdmProductDetailMapper.class).doMaterialReplaceUpdate(ypd);
					// 物料充当脱单履历
					this.getBean(MesApiDesignInfoImpl.class).createMatLog(lpmd.get(0), "厂内合同脱单",userName, "" , "-1", pm.getObject_no());
					if(++num == lpm.size()) {
						rm.setData("200");
						rm.setMsgInfo("脱单成功!");
						return rm ;
					}
					continue ;
				}
				
				// 如果子卷已经挂单不允许脱单
				int child = this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null,
						"mat_object_no_vt = '" + pm.getObject_no_vt()
								+ "' and object_no is not null and nvl(invalid_flg,0) = 0");
				if (child > 0) {
					rm.setState("500");
					rm.setMsgInfo("虚拟物料[" + pm.getObject_no_vt() + "]对应的成品已经挂单,不允许脱单!");
					return rm;
				}
				if (lpmd == null || lpmd.size() == 0) {
					rm.setState("500");
					rm.setMsgInfo("虚拟物料[" + pm.getObject_no_vt() + "]信息不存在");
					return rm;
				}

				boolean V_CanDelete_VT = false;

				// 如果是成品挂单
				if(lpmd.get(0).getIs_fin_prods()==1) {
					V_CanDelete_VT = true ;
					// 判断是否分条或者开平工序成品虚拟物料(是否是最终成品)----2018-07-08----- 2018-09-20 罩退 ----2018-10-17平整	
				} else if ((processpoint.slitting_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.cross_cutting_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.anneal_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.smooth_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.rolling_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.pickle_code.equals(lpmd.get(0).getPrev_process_code()))
						&& !"1".equals(lpmd.get(0).getIs_next_finished())) {
//					if (lpmd.get(0).getIs_next_finished() != null && !"1".equals(lpmd.get(0).getIs_next_finished())) { 2018-11-14 修改多工序一起生产,第二个工序的虚拟物料信息上下工序都存在
					// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
					PlnProdorderStatistic pps = new PlnProdorderStatistic();
					pps.setProd_order_no(lpmd.get(0).getProd_order_no());
					if ("1".equals(lpmd.get(0).getIs_replaced())) {
						pps.setReplaced(ypd.getFactweight() == null ? null : (-ypd.getFactweight()));
						pps.setReplaced_cnt(-1);
					}
					pps.setUnscheduled(ypd.getFactweight());
					pps.setUnscheduled_cnt(1);
					// pps.setReplaced_times(-1);
					this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

					// 修改订单进程表[PLN_ORDER_STATISTIC]
					PlnOrderStatistic pos = new PlnOrderStatistic();
					pos.setOrder_no(lpmd.get(0).getOrder_no());
					if ("1".equals(lpmd.get(0).getIs_replaced())) {
						pos.setReplaced(ypd.getFactweight() == null ? null : (-ypd.getFactweight()));
						pos.setReplaced_cnt(-1);
					}
					pos.setUnscheduled(ypd.getFactweight());
					pos.setUnscheduled_cnt(1);
					// pos.setReplaced_times(-1);

					this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
//					}

				} else if (processpoint.slitting_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (lpmd.get(0).getLw_plan_no() != null && !"".equals(lpmd.get(0).getLw_plan_no())) {
						PlnLengthwisePlanDetail plpd = new PlnLengthwisePlanDetail();
						plpd.setLw_plan_no(lpmd.get(0).getLw_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnLengthwisePlanDetail> lplpd = this.getMapper(PlnLengthwisePlanDetailMapper.class)
								.find(plpd, 0, 1);

						if (lplpd != null && lplpd.size() > 0) {
							if ("5BLW02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BLW01, 则脱掉虚拟物料的纵剪计划
							if ("5BLW01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getBean(PlnLengthwisePlanServiceImpl.class).doCheckCancelPlanChild(lplpd);
							}
						}
					}
					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");

						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_lw_divorced(ypd.getFactweight());
						pps.setMat_lw_divorced_cnt(1);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_lw_divorced(ypd.getFactweight());
						pos.setMat_lw_divorced_cnt(1);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);

					} else {
						V_CanDelete_VT = true;
					}

				} else if (processpoint.cross_cutting_code.equals(lpmd.get(0).getNext_dsn_process_code())) {

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

						if (lplpd != null && lplpd.size() > 0) {
							if ("5BCL02".compareTo(lplpd.get(0).getStatus()) >= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的横剪计划
							if ("5BCL01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getBean(PlnCuttolengthPlanServiceImpl.class).doCheckCancelPlanChild(lplpd);
							}
						}
					}

					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");

						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_cl_divorced(ypd.getFactweight());
						pps.setMat_cl_divorced_cnt(1);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_cl_divorced(ypd.getFactweight());
						pos.setMat_cl_divorced_cnt(1);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				} else if (processpoint.anneal_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (lpmd.get(0).getAn_plan_no() != null && !"".equals(lpmd.get(0).getAn_plan_no())) {
						PlnAnnealPlanDetail plpd = new PlnAnnealPlanDetail();
						plpd.setAn_plan_no(lpmd.get(0).getAn_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnAnnealPlanDetail> lplpd = this.getMapper(PlnAnnealPlanDetailMapper.class).find(plpd, 0,
								1);

						if (lplpd != null && lplpd.size() > 0) {
							if ("5BAN02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的罩退计划
							if ("5BAN01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getBean(PlnAnnealDsnMultinfoServiceImpl.class).doCheckCancelPlanChild(lplpd);
							}
						}
					}

					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");

						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_an_divorced(ypd.getFactweight());
						pps.setMat_an_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_an_divorced(ypd.getFactweight());
						pos.setMat_an_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateSrPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				} else if (processpoint.smooth_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (Utils.isNotEmpty(lpmd.get(0).getSr_plan_no())) {
						PlnSkinrollingPlanDetail plpd = new PlnSkinrollingPlanDetail();
						plpd.setSr_plan_no(lpmd.get(0).getSr_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnSkinrollingPlanDetail> lplpd = this.getMapper(PlnSkinrollingPlanDetailMapper.class)
								.find(plpd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BSR02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的平整计划
							if ("5BSR01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getBean(PlnSkinrollingDsnMultinfoServiceImpl.class).doCheckCancelPlanChild(lplpd);
							}
						}
					}

					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");

						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_sr_divorced(ypd.getFactweight());
						pps.setMat_sr_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_sr_divorced(ypd.getFactweight());
						pos.setMat_sr_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateSrPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				} else if (processpoint.rolling_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (Utils.isNotEmpty(lpmd.get(0).getSr_plan_no())) {
						PlnRollingPlanDetail plpd = new PlnRollingPlanDetail();
						plpd.setRl_plan_no(lpmd.get(0).getRl_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnRollingPlanDetail> lplpd = this.getMapper(PlnRollingPlanDetailMapper.class)
								.find(plpd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BRL02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的平整计划
							if ("5BRL01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getBean(PlnRollingDsnMultinfoServiceImpl.class).doCheckCancelPlanChild(lplpd);
							}
						}
					}

					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");

						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_rl_divorced(ypd.getFactweight());
						pps.setMat_rl_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_rl_divorced(ypd.getFactweight());
						pos.setMat_rl_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateRlPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				}else if (processpoint.pickle_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (Utils.isNotEmpty(lpmd.get(0).getPc_plan_no())) {
						PlnPicklePlanDetail pppd = new PlnPicklePlanDetail();
						pppd.setPc_plan_no(lpmd.get(0).getPc_plan_no());
						pppd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnPicklePlanDetail> lplpd = this.getMapper(PlnPicklePlanDetailMapper.class)
								.find(pppd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BPC02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								//throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的平整计划
							if ("5BPC01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getBean(PlnPickleDsnMultinfoServiceImpl.class).doCheckCancelPlanChild(lplpd);
							}
						}
					}

					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");

						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_pc_divorced(ypd.getFactweight());
						pps.setMat_pc_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_pc_divorced(ypd.getFactweight());
						pos.setMat_pc_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdatePcPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				}else {
					rm.setState("500");
					rm.setMsgInfo("虚拟物料不是分条/开平/罩退/平整/轧制/酸洗工序的原料或成品物料，无法脱单！\n (请刷新检查分条/开平坯料设计是否有变化)");
					return rm;
				}

				// 解除 实际和虚拟 物料的绑定
				if (V_CanDelete_VT) {
					lpmd.get(0).setDivorced_times(null);
//					String temp = "";
					String[] path = null;
					ArrayList<String> validpath = new ArrayList<>();
//					temp = lpmd.get(0).getCreate_process_code() + StringUtils
//							.substringAfter(pln.get(0).getWhole_process_codes(), lpmd.get(0).getCreate_process_code());
//					if (lpmd.get(0).getProc_repeat_index() == 2) {
//						temp = StringUtils
//								.substringAfter(
//										StringUtils.substringAfter(pln.get(0).getWhole_process_codes(),
//												lpmd.get(0).getCreate_process_code()),
//										lpmd.get(0).getCreate_process_code());
//					}
//					path = temp.split("-");
					path = pln.get(0).getWhole_process_codes().split("-");
					validpath = this.getBean(MesApiDesignInfoImpl.class).getProcessPath(path);
					if(lpmd.get(0).getIs_fin_prods()==1) {
						// 删除虚拟物料
						this.getMapper(PlnMaterielDetailMapper.class).delete(lpmd.get(0).getSerial_no());
					}else {
						// 调用函数 【删除虚拟母卷sheet】:传入参数(虚拟母卷号)以及其后工序
						doCancelChild(lpmd);
					}
					// 修改生产订单以及订单进程量
					this.getBean(MesApiDesignInfoImpl.class).updateOrderStatic(pln.get(0).getProd_order_no(),
							pln.get(0).getOrder_no(), validpath.toString(), ypd.getFactweight(), false);
				}

				// 修改虚拟物料表
				// 脱单次数[DIVORCED_TIMES]+=1;
				if (!V_CanDelete_VT) {
					lpmd.get(0).setDivorced_times(
							(lpmd.get(0).getDivorced_times() == null ? 0 : lpmd.get(0).getDivorced_times()) + 1);
					lpmd.get(0).setObject_no(null);
					// 将虚拟物料表的OBJECT_NO 物料(卷/带/板)号设置为NULL
					this.getMapper(PlnMaterielDetailMapper.class).doMaterialReplaceUpdate(lpmd.get(0));
				}

				// 调用物流接口，将实物物料对应的虚拟物料号置位NULL
				this.getMapper(YdmProductDetailMapper.class).doMaterialReplaceUpdate(ypd);
				mmrl.setPline_code(lpmd.get(0).getPline_code());
				mmrl.setObject_type(lpmd.get(0).getObject_type());
				mmrl.setObject_no_vt(pm.getObject_no_vt());
				mmrl.setOrder_no(lpmd.get(0).getOrder_no());
				mmrl.setProd_order_no(lpmd.get(0).getProd_order_no());
				mmrl.setLw_design_no(lpmd.get(0).getLw_design_no());
				mmrl.setCl_design_no(lpmd.get(0).getCl_design_no());
				mmrl.setRl_design_no(lpmd.get(0).getRl_design_no());
				mmrl.setAn_design_no(lpmd.get(0).getAn_design_no());
				mmrl.setLw_plan_no(lpmd.get(0).getLw_plan_no());
				mmrl.setCl_plan_no(lpmd.get(0).getCl_plan_no());
				mmrl.setRl_plan_no(lpmd.get(0).getRl_plan_no());
				mmrl.setAn_plan_no(lpmd.get(0).getAn_plan_no());
			}
			this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
			// 清空物料附加信息
			this.getBean(MesApiDesignInfoImpl.class).updateMaterielExinfo(pm.getObject_no());			
			//日志
			MesOprLog mol = new MesOprLog("生产管理", "脱单管理", "脱单", userName, opr_time, mmrl.getObject_no(), null, null, null, "");
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		rm.setState("200");
		return rm;
	}
	
	
	/**
	 *  脱单接口(五合一)质量调用 
	 * 
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doMatReplaceAuto(CommonPage<PlnMaterielDetail> oci) throws Exception {
		ResultModel rm = new ResultModel();
		String userName = oci.getMemo1() ;
		userName = userName == null ? (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME) : userName ;
		List<PlnMaterielDetail> lpm = oci.getObjectList();
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		// 物料充当脱单履历
		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;
		}
		
		// 脱单记数
		int num = 0 ;
		
		for (PlnMaterielDetail pm : lpm) {
			YdmProductDetail ypd = new YdmProductDetail();
//			ypd.setObject_no_vt(pm.getObject_no_vt());
			ypd.setCoilno(pm.getObject_no());// 卷号
			// 卷号是唯一的值
			List<YdmProductDetail> lypd = this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
			// 不存在物料信息
			if (lypd == null || lypd.size() == 0) {
				rm.setState("500");
				rm.setMsgInfo("物料[" + ypd.getCoilno() + "]库存信息不存在！");
				return rm;
			}
			// 卷号是唯一的值
			// 实际物料 不是在库状态
			if (!"0".equals(lypd.get(0).getState())) {
				rm.setState("500");
				rm.setMsgInfo("物料[" + ypd.getCoilno() + "]不是[在库]状态，不能脱单！");
				return rm;
			}
			
			// 物料充当脱单履历表
			PlnMatReplaceLog mmrl = new PlnMatReplaceLog();
			mmrl.setSerial_no(iNo++);
			mmrl.setOpt_type("0");
			mmrl.setStatus(lypd.get(0).getState());
			mmrl.setCreate_man_name(userName);
			mmrl.setCreate_time(new Date());
			mmrl.setObject_no(pm.getObject_no());
			mmrl.setRemark(pm.getRemark());
			
			if (pm.getObject_no_vt() == null || "".equals(pm.getObject_no_vt().trim())) {
				// 虚拟物料号不存在，则调用逻辑1
				// 对物料对应的生产订单，查询生产订单表[PLN_PRODORDER],若不存在信息，则报错“生产订单[xxx]信息不存在”。
				PlnProdorder pp = new PlnProdorder();
				pp.setOrder_no(lypd.get(0).getOrderno());
				List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 0);
				if (lpp == null || lpp.size() == 0) {
					// 生产订单[xxx]信息不存在
					rm.setState("500");
					rm.setMsgInfo("生产订单[" + pp.getOrder_no() + "]信息不存在");
					return rm;
				}
				// 验证生产订单是否锁定
				boolean flag = this.getService(MesApiDesignInfoService.class).pOrdIsLocked(lypd.get(0).getProdorderno());
				if (flag) {
					throw new Exception("生产订单已经锁定[订单变更中],不允许脱单!");
				}
				
				// 最后一道工序为分条工序
				// if(processpoint.slitting_code.equals(this.getBean(QmsApiServiceImpl.class).GetWrkPlanCode(pp.getOrder_no()))){
				// 获得生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(lpp.get(0).getProd_order_no());
				pps.setReplaced(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
				pps.setReplaced_cnt(-1);
				pps.setUnscheduled(lypd.get(0).getFactweight());
				pps.setDivorced_times(1);
				
				
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
				
				// 修改订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos = new PlnOrderStatistic();
				pos.setOrder_no(lpp.get(0).getOrder_no());
				pos.setReplaced(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
				pos.setReplaced_cnt(-1);
				pos.setUnscheduled(lypd.get(0).getFactweight());
				pos.setDivorced_times(1);
				this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
				
				// 将 虚拟物料表 的 OBJECT_NO 物料(卷/带/板)号 设置为NULL
				List<PlnMaterielDetail> pmds = this.getMapper(PlnMaterielDetailMapper.class)
						.findWithCondition(null, " object_no = '"+pm.getObject_no()+"' and nvl(invalid_flg,0) = 0 ", null, 0, 1);
				if (Utils.isNotEmpty(pmds)) {
					pmds.get(0).setObject_no(null);
					pmds.get(0).setDivorced_times(
							(pmds.get(0).getDivorced_times() == null ? 0 : pmds.get(0).getDivorced_times()) + 1);
					this.getMapper(PlnMaterielDetailMapper.class).doMaterialReplaceUpdate(pmds.get(0));
					
				}
				
				// 调用物流接口，将 实物物料 对应的虚拟物料号 置位NULL
				this.getMapper(YdmProductDetailMapper.class).doMaterialReplaceUpdate(lypd.get(0));
				mmrl.setOrder_no(lpp.get(0).getOrder_no());
				mmrl.setProd_order_no(lypd.get(0).getProdorderno());
				
			} else {
				// 虚拟物料号存在，则调用逻辑2
				// 对物料对应的虚拟物料号，查询虚拟物料表[PLN_MATERIEL_DETAIL]根据虚拟物料号查询物料信息
				PlnMaterielDetail pmd = new PlnMaterielDetail();
				pmd.setObject_no_vt(pm.getObject_no_vt());
				List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmd, 0, 0);
				
				// 查询生产订单信息
				List<PlnProdorder> pln = this.getMapper(PlnProdorderMapper.class).findWithCondition(null,
						" prod_order_no = '" + lpmd.get(0).getProd_order_no() + "'", null, 0, 1);
				if (Utils.isEmpty(pln)) {
					rm.setState("500");
					rm.setMsgInfo("生产订单[" + pm.getProd_order_no() + "]信息不存在!");
					return rm;
				}
				
				// 验证生产订单是否锁定
				boolean flag = this.getService(MesApiDesignInfoService.class).pOrdIsLocked(lypd.get(0).getProdorderno());
				if (flag) {
					throw new Exception("生产订单已经锁定[订单变更中],不允许脱单!");
				}
				
				// 厂内合同并且已生生产完成--脱单,修改库存信息
				boolean flag_Ct = this.getService(MesApiDesignInfoService.class).getContractType(lpmd.get(0).getProd_order_no());
				boolean flag_Mf = this.getService(MesApiDesignInfoService.class).matIsFinish(pm.getObject_no());
				if (flag_Mf && flag_Ct) {
					this.getMapper(YdmProductDetailMapper.class).doMaterialReplaceUpdate(lypd.get(0));
					// 物料充当脱单履历
					this.getService(MesApiDesignInfoService.class).createMatLog(lpmd.get(0), "厂内合同脱单",userName, "" , "-1", pm.getObject_no());
					if(++num == lpm.size()) {
						rm.setData("200");
						rm.setMsgInfo("脱单成功!");
						return rm ;
					}
					continue ;
				}
				
				// 如果子卷已经挂单不允许脱单
				int child = this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null,
						"mat_object_no_vt = '" + pm.getObject_no_vt()
						+ "' and object_no is not null and nvl(invalid_flg,0) = 0");
				if (child > 0) {
					rm.setState("500");
					rm.setMsgInfo("虚拟物料[" + pm.getObject_no_vt() + "]对应的成品已经挂单,不允许脱单!");
					return rm;
				}
				if (lpmd == null || lpmd.size() == 0) {
					rm.setState("500");
					rm.setMsgInfo("虚拟物料[" + pm.getObject_no_vt() + "]信息不存在");
					return rm;
				}
				
				boolean V_CanDelete_VT = false;
				if(lpmd.get(0).getIs_fin_prods()==1) {
					V_CanDelete_VT = true;
				}
				// 判断是否分条或者开平工序成品虚拟物料(是否是最终成品)----2018-07-08----- 2018-09-20 罩退 ----2018-10-17平整
				else if ((processpoint.slitting_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.cross_cutting_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.anneal_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.smooth_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.rolling_code.equals(lpmd.get(0).getPrev_process_code())
						|| processpoint.pickle_code.equals(lpmd.get(0).getPrev_process_code()))
						&& !"1".equals(lpmd.get(0).getIs_next_finished())) {
//					if (lpmd.get(0).getIs_next_finished() != null && !"1".equals(lpmd.get(0).getIs_next_finished())) { 2018-11-14 修改多工序一起生产,第二个工序的虚拟物料信息上下工序都存在
					// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
					PlnProdorderStatistic pps = new PlnProdorderStatistic();
					pps.setProd_order_no(lpmd.get(0).getProd_order_no());
					if ("1".equals(lpmd.get(0).getIs_replaced())) {
						pps.setReplaced(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
						pps.setReplaced_cnt(-1);
					}
					pps.setUnscheduled(lypd.get(0).getFactweight());
					pps.setUnscheduled_cnt(1);
					// pps.setReplaced_times(-1);
					this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
					
					// 修改订单进程表[PLN_ORDER_STATISTIC]
					PlnOrderStatistic pos = new PlnOrderStatistic();
					pos.setOrder_no(lpmd.get(0).getOrder_no());
					if ("1".equals(lpmd.get(0).getIs_replaced())) {
						pos.setReplaced(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
						pos.setReplaced_cnt(-1);
					}
					pos.setUnscheduled(lypd.get(0).getFactweight());
					pos.setUnscheduled_cnt(1);
					this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
					
				} else if (processpoint.slitting_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (lpmd.get(0).getLw_plan_no() != null && !"".equals(lpmd.get(0).getLw_plan_no())) {
						PlnLengthwisePlanDetail plpd = new PlnLengthwisePlanDetail();
						plpd.setLw_plan_no(lpmd.get(0).getLw_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnLengthwisePlanDetail> lplpd = this.getMapper(PlnLengthwisePlanDetailMapper.class)
								.find(plpd, 0, 1);
						
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BLW02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BLW01, 则脱掉虚拟物料的纵剪计划
							if ("5BLW01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getService(PlnLengthwisePlanService.class).doCancelPlanAuto(lplpd,userName);
							}
						}
					}
					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");
						
						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_lw_divorced(lypd.get(0).getFactweight());
						pps.setMat_lw_divorced_cnt(1);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
						
						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_lw_divorced(lypd.get(0).getFactweight());
						pos.setMat_lw_divorced_cnt(1);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
						
					} else {
						V_CanDelete_VT = true;
					}
					
				} else if (processpoint.cross_cutting_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					
					if (lpmd.get(0).getCl_plan_no() != null && !"".equals(lpmd.get(0).getCl_plan_no())) {
						PlnCuttolengthPlanDetail plpd = new PlnCuttolengthPlanDetail();
						plpd.setCl_plan_no(lpmd.get(0).getCl_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnCuttolengthPlanDetail> lplpd = this.getMapper(PlnCuttolengthPlanDetailMapper.class)
								.find(plpd, 0, 1);
						
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BCL02".compareTo(lplpd.get(0).getStatus()) >= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的横剪计划
							if ("5BCL01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getService(PlnCuttolengthPlanService.class).doCancelPlanAuto(lplpd,userName);
							}
						}
					}
					
					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");
						
						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_cl_divorced(lypd.get(0).getFactweight());
						pps.setMat_cl_divorced_cnt(1);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
						
						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_cl_divorced(lypd.get(0).getFactweight());
						pos.setMat_cl_divorced_cnt(1);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				} else if (processpoint.anneal_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (lpmd.get(0).getAn_plan_no() != null && !"".equals(lpmd.get(0).getAn_plan_no())) {
						PlnAnnealPlanDetail plpd = new PlnAnnealPlanDetail();
						plpd.setAn_plan_no(lpmd.get(0).getAn_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnAnnealPlanDetail> lplpd = this.getMapper(PlnAnnealPlanDetailMapper.class).find(plpd, 0,
								1);
						
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BAN02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的罩退计划
							if ("5BAN01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getService(PlnAnnealDsnMultinfoService.class).doCancelPlanAuto(lplpd,userName);
							}
						}
					}
					
					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");
						
						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_an_divorced(lypd.get(0).getFactweight());
						pps.setMat_an_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
						
						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_an_divorced(lypd.get(0).getFactweight());
						pos.setMat_an_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateSrPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				} else if (processpoint.smooth_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (Utils.isNotEmpty(lpmd.get(0).getSr_plan_no())) {
						PlnSkinrollingPlanDetail plpd = new PlnSkinrollingPlanDetail();
						plpd.setSr_plan_no(lpmd.get(0).getSr_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnSkinrollingPlanDetail> lplpd = this.getMapper(PlnSkinrollingPlanDetailMapper.class)
								.find(plpd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BSR02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的平整计划
							if ("5BSR01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getService(PlnSkinrollingDsnMultinfoService.class).doCancelPlanAuto(lplpd,userName);
							}
						}
					}
					
					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");
						
						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_sr_divorced(lypd.get(0).getFactweight());
						pps.setMat_sr_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
						
						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_sr_divorced(lypd.get(0).getFactweight());
						pos.setMat_sr_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateSrPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				} else if (processpoint.rolling_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (Utils.isNotEmpty(lpmd.get(0).getSr_plan_no())) {
						PlnRollingPlanDetail plpd = new PlnRollingPlanDetail();
						plpd.setRl_plan_no(lpmd.get(0).getRl_plan_no());
						plpd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnRollingPlanDetail> lplpd = this.getMapper(PlnRollingPlanDetailMapper.class)
								.find(plpd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BRL02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的平整计划
							if ("5BRL01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getService(PlnRollingDsnMultinfoService.class).doCancelPlanAuto(lplpd,userName);
							}
						}
					}
					
					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");
						
						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_rl_divorced(lypd.get(0).getFactweight());
						pps.setMat_rl_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
						
						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_rl_divorced(lypd.get(0).getFactweight());
						pos.setMat_rl_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdateRlPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				}else if (processpoint.pickle_code.equals(lpmd.get(0).getNext_dsn_process_code())) {
					if (Utils.isNotEmpty(lpmd.get(0).getPc_plan_no())) {
						PlnPicklePlanDetail pppd = new PlnPicklePlanDetail();
						pppd.setPc_plan_no(lpmd.get(0).getPc_plan_no());
						pppd.setObject_no_vt(lpmd.get(0).getObject_no_vt());
						List<PlnPicklePlanDetail> lplpd = this.getMapper(PlnPicklePlanDetailMapper.class)
								.find(pppd, 0, 1);
						if (lplpd != null && lplpd.size() > 0) {
							if ("5BPC02".compareTo(lplpd.get(0).getStatus()) <= 0) {
								throw new Exception("物料[" + pm.getObject_no() + "]已经开始生产，不允许脱单！");
							}
							// 如果找到 且 记录的 STATUS =5BCL01, 则脱掉虚拟物料的平整计划
							if ("5BPC01".compareTo(lplpd.get(0).getStatus()) == 0) {
								this.getService(PlnPickleDsnMultinfoService.class).doCancelPlanAuto(lplpd,userName);
							}
						}
					}
					
					// (原料)操作次数[OPT_TIMES]>0 ，则 需重新加工(原料)[NEED_EXTOPT ]标记为 1
					if (lpmd.get(0).getOpt_times() != null && lpmd.get(0).getOpt_times() > 0) {
						lpmd.get(0).setNeed_extopt("1");
						
						// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
						PlnProdorderStatistic pps = new PlnProdorderStatistic();
						pps.setProd_order_no(lpmd.get(0).getProd_order_no());
						pps.setMat_pc_divorced(lypd.get(0).getFactweight());
						pps.setMat_pc_divorced_cnt(1l);
						this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
						
						// 修改订单进程表[PLN_ORDER_STATISTIC]
						PlnOrderStatistic pos = new PlnOrderStatistic();
						pos.setOrder_no(lpmd.get(0).getOrder_no());
						pos.setMat_pc_divorced(lypd.get(0).getFactweight());
						pos.setMat_pc_divorced_cnt(1l);
						this.getMapper(PlnOrderStatisticMapper.class).doUpdatePcPlaned(pos);
					} else {
						V_CanDelete_VT = true;
					}
				}else {
					rm.setState("500");
					rm.setMsgInfo("虚拟物料不是分条/开平/罩退/平整/轧制/酸洗工序的原料或成品物料，无法脱单！\n (请刷新检查分条/开平坯料设计是否有变化)");
					return rm;
				}
				
				// 解除 实际和虚拟 物料的绑定
				if (V_CanDelete_VT) {
					lpmd.get(0).setDivorced_times(null);
//					String temp = "";
					String[] path = null;
					ArrayList<String> validpath = new ArrayList<>();
					path = pln.get(0).getWhole_process_codes().split("-");
					validpath = this.getService(MesApiDesignInfoService.class).getProcessPath(path);
					if(lpmd.get(0).getIs_fin_prods()==1) {
						// 删除虚拟物料
						this.getMapper(PlnMaterielDetailMapper.class).delete(lpmd.get(0).getSerial_no());
					}else {
						// 调用函数 【删除虚拟母卷sheet】:传入参数(虚拟母卷号)以及其后工序
						this.getService(PlnMaterielDetailService.class).doCancelChild(lpmd);
					}
					// 修改生产订单以及订单进程量
					this.getService(MesApiDesignInfoService.class).updateOrderStatic(pln.get(0).getProd_order_no(),
							pln.get(0).getOrder_no(), validpath.toString(), lypd.get(0).getFactweight(), false);
				}
				
				// 修改虚拟物料表
				// 脱单次数[DIVORCED_TIMES]+=1;
				if (!V_CanDelete_VT) {
					lpmd.get(0).setDivorced_times(
							(lpmd.get(0).getDivorced_times() == null ? 0 : lpmd.get(0).getDivorced_times()) + 1);
					lpmd.get(0).setObject_no(null);
					// 将虚拟物料表的OBJECT_NO 物料(卷/带/板)号设置为NULL
					this.getMapper(PlnMaterielDetailMapper.class).doMaterialReplaceUpdate(lpmd.get(0));
				}
				
				// 调用物流接口，将实物物料对应的虚拟物料号置位NULL
				this.getMapper(YdmProductDetailMapper.class).doMaterialReplaceUpdate(lypd.get(0));
				mmrl.setPline_code(lpmd.get(0).getPline_code());
				mmrl.setObject_type(lpmd.get(0).getObject_type());
				mmrl.setObject_no_vt(pm.getObject_no_vt());
				mmrl.setOrder_no(lpmd.get(0).getOrder_no());
				mmrl.setProd_order_no(lpmd.get(0).getProd_order_no());
				mmrl.setLw_design_no(lpmd.get(0).getLw_design_no());
				mmrl.setCl_design_no(lpmd.get(0).getCl_design_no());
				mmrl.setRl_design_no(lpmd.get(0).getRl_design_no());
				mmrl.setAn_design_no(lpmd.get(0).getAn_design_no());
				mmrl.setLw_plan_no(lpmd.get(0).getLw_plan_no());
				mmrl.setCl_plan_no(lpmd.get(0).getCl_plan_no());
				mmrl.setRl_plan_no(lpmd.get(0).getRl_plan_no());
				mmrl.setAn_plan_no(lpmd.get(0).getAn_plan_no());
			}
			this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
			// 清空物料附加信息
			this.getService(MesApiDesignInfoService.class).updateMaterielExinfo(pm.getObject_no());
		}
		rm.setState("200");
		return rm;
	}

	/**
	 * 删除虚拟母卷
	 */
	public void doCancelChild(List<PlnMaterielDetail> lpmd) 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);
		for (PlnMaterielDetail pmd : lpmd) {
			// 读取虚拟物料表【PLN_MATERIEL_DETAIL】，获取虚拟母卷信息
			List<PlnMaterielDetail> lpmdq = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"object_no_vt = '" + pmd.getObject_no_vt() + "' and nvl(invalid_flg,0) = 0", null, 0, 1);
			if (lpmdq == null || lpmdq.size() == 0) {
				throw new Exception("未找到虚拟物料[" + pmd.getObject_no_vt() + "]");
			}

			// 判断虚拟母卷是否进行过生产：IF(OPT_TIMES>0 OR NEED_EXTOPT >0 ),如果成立，则报错退出
			if ((lpmdq.get(0).getOpt_times() != null && lpmdq.get(0).getOpt_times() > 0)
					|| (lpmdq.get(0).getNeed_extopt() != null && "0".compareTo(lpmdq.get(0).getNeed_extopt()) < 0)
					|| (lpmdq.get(0).getIs_next_finished() != null
							&& "0".compareTo(lpmdq.get(0).getIs_next_finished()) < 0)) {
				throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已进行过生产，无法删除！");
			}
			// 真正意义上的母卷 并非某各环节
			if (Utils.isEmpty(lpmdq.get(0).getPrev_process_code())) {
				// 判断以下字段是否有值
				if (lpmdq.get(0).getLw_plan_no() != null && !"".equals(lpmdq.get(0).getLw_plan_no())) {
					throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做分条计划，无法删除！");
				}
				if (lpmdq.get(0).getCl_plan_no() != null && !"".equals(lpmdq.get(0).getCl_plan_no())) {
					throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做开平计划，无法删除！");
				}
				if (lpmdq.get(0).getRl_plan_no() != null && !"".equals(lpmdq.get(0).getRl_plan_no())) {
					throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做轧制计划，无法删除！");
				}
				if (lpmdq.get(0).getAn_plan_no() != null && !"".equals(lpmdq.get(0).getAn_plan_no())) {
					throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做罩退计划，无法删除！");
				}
				if (Utils.isNotEmpty(lpmdq.get(0).getSr_plan_no())) {
					throw new Exception("虚拟物料[" + pmd.getObject_no_vt() + "]已做平整计划，无法删除！");
				}
			}
			// 累加 虚拟子卷重量, 虚拟子卷个数
//			double v_total_wgt=0;
//			int v_total_num=0;

			// 循环处理 该虚拟母卷对应的 所有虚拟子卷
			PlnMaterielDetail pmdcq = new PlnMaterielDetail();
			pmdcq.setMat_object_no_vt(lpmdq.get(0).getObject_no_vt());
			List<PlnMaterielDetail> lpmdc = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
					"mat_object_no_vt = '" + lpmdq.get(0).getObject_no_vt() + "' and nvl(invalid_flg,0) =0", "", 0, 0);
			if (Utils.isNotEmpty(lpmdc)) {
				for (PlnMaterielDetail pmdc : lpmdc) {
					List<PlnMaterielDetail> child = new ArrayList<>();
					// 如果虚拟子卷的[NEXT_DSN_PROCESS_CODE]==null 或 =="", 则 删除虚拟子卷。
					if (pmdc.getNext_dsn_process_code() == null || "".equals(pmdc.getNext_dsn_process_code())) {
						this.getMapper(PlnMaterielDetailMapper.class).doDeleteId(pmdc);
					} else {
						child.add(pmdc);
						doCancelChild(child);
					}
	//				v_total_wgt+=pmdc.getSingle_weight().doubleValue();
	//				v_total_num++;
				}
			}
			String v_dsn_no = "";

			// 根据母卷 生成的设计工序【CREATE_PROCESS_CODE】判断 == ‘分条工序代码’
			if (processpoint.slitting_code.equals(lpmdq.get(0).getNext_process_code())) {
				// 根据 虚拟母卷的 生成时的设计号CREATE_DESIGN_NO，修改对应 分条设计主表记录
				// DESIGN_QUANTITY 设计原料卷总数 -= 1; DESIGN_WEIGHT 设计原料卷总重 -= MAT_SINGLE_WEIGHT
				// 原料卷单重
				PlnLengthwiseDsnMain pldm = new PlnLengthwiseDsnMain();
				pldm.setLw_design_no(lpmdq.get(0).getCreate_design_no());
				pldm.setDesign_weight(-lpmdq.get(0).getSingle_weight());
				pldm.setDesign_quantity(-1);
				this.getMapper(PlnLengthwiseDsnMainMapper.class).doUpdatePlanedWgt(pldm);
				v_dsn_no = lpmdq.get(0).getLw_design_no();
				// 根据母卷 生成的设计工序【CREATE_PROCESS_CODE】判断 == ‘开平工序代码’
			} else if (processpoint.cross_cutting_code.equals(lpmdq.get(0).getNext_process_code())) {
				// 根据 虚拟母卷的 生成时的设计号CREATE_DESIGN_NO，修改对应 开平设计主表记录
				// DESIGN_QUANTITY 设计原料卷总数 -= 1; DESIGN_WEIGHT 设计原料卷总重 -= MAT_SINGLE_WEIGHT
				// 原料卷单重
				PlnCuttolengthDsnMain pldm = new PlnCuttolengthDsnMain();
				pldm.setCl_design_no(lpmdq.get(0).getCreate_design_no());
				pldm.setDesign_weight(-lpmdq.get(0).getSingle_weight());
				pldm.setDesign_quantity(-1);
				this.getMapper(PlnCuttolengthDsnMainMapper.class).doUpdatePlanedWgt(pldm);
				v_dsn_no = lpmdq.get(0).getCl_design_no();
				// 根据母卷 生成的设计工序【CREATE_PROCESS_CODE】判断 == ‘罩退工序代码’
			} else if (processpoint.anneal_code.equals(lpmdq.get(0).getNext_process_code())) {
				// 根据 虚拟母卷的 生成时的设计号CREATE_DESIGN_NO，修改对应 罩退设计主表记录
				// DESIGN_QUANTITY 设计原料卷总数 -= 1; DESIGN_WEIGHT 设计原料卷总重 -= MAT_SINGLE_WEIGHT
				// 原料卷单重
				PlnAnnealDsnMain pldm = new PlnAnnealDsnMain();
				pldm.setAn_design_no(lpmdq.get(0).getCreate_design_no());
				pldm.setDesign_weight(-lpmdq.get(0).getSingle_weight());
				pldm.setDesign_quantity(-1);
				this.getMapper(PlnAnnealDsnMainMapper.class).doUpdatePlanedWgt(pldm);
				v_dsn_no = lpmdq.get(0).getAn_design_no();
			} else if (processpoint.smooth_code.equals(lpmdq.get(0).getNext_process_code())) {
				// 根据 虚拟母卷的 生成时的设计号CREATE_DESIGN_NO，修改对应 罩退设计主表记录
				// DESIGN_QUANTITY 设计原料卷总数 -= 1; DESIGN_WEIGHT 设计原料卷总重 -= MAT_SINGLE_WEIGHT
				// 原料卷单重
				PlnSkinrollingDsnMain pldm = new PlnSkinrollingDsnMain();
				pldm.setSr_design_no(lpmdq.get(0).getCreate_design_no());
				pldm.setDesign_weight(-lpmdq.get(0).getSingle_weight());
				pldm.setDesign_quantity(-1);
				this.getMapper(PlnSkinrollingDsnMainMapper.class).doUpdatePlanedWgt(pldm);
				v_dsn_no = lpmdq.get(0).getAn_design_no();
			} else if (processpoint.rolling_code.equals(lpmdq.get(0).getNext_process_code())) {
				// 根据 虚拟母卷的 生成时的设计号CREATE_DESIGN_NO，修改对应 罩退设计主表记录
				// DESIGN_QUANTITY 设计原料卷总数 -= 1; DESIGN_WEIGHT 设计原料卷总重 -= MAT_SINGLE_WEIGHT
				// 原料卷单重
				PlnRollingDsnMain pldm = new PlnRollingDsnMain();
				pldm.setRl_design_no(lpmdq.get(0).getCreate_design_no());
				pldm.setDesign_weight(-lpmdq.get(0).getSingle_weight());
				pldm.setDesign_quantity(-1);
				this.getMapper(PlnRollingDsnMainMapper.class).doUpdatePlanedWgt(pldm);
				v_dsn_no = lpmdq.get(0).getRl_design_no();
			}

			// 删除虚拟母卷信息
			this.getMapper(PlnMaterielDetailMapper.class).doDeleteId(lpmdq.get(0));

			// (临时变量：v_设计号 = 虚拟母卷的下一个工序)
			// 统计虚拟物料表中,母卷设计号对应的母板个数
			PlnMaterielDetail pmdcount = new PlnMaterielDetail();
			pmdcount.setCreate_design_no(v_dsn_no);
			pmdcount.setIs_mat(1);
			int icount = this.getMapper(PlnMaterielDetailMapper.class).count(pmdcount);
			// 如果 (统计个数 == 0
			if (icount == 0) {
				if ("DLW".equals(v_dsn_no.substring(0, 3))) {
					// 删除 分条拼料信息表【PLN_LENGTHWISE_DSN_MULTINFO】: where LW_DESIGN_NO = v_设计号
					this.getMapper(PlnLengthwiseDsnMultinfoMapper.class).doDelete(v_dsn_no);

					// 删除 分条设计主表【PLN_LENGTHWISE_DSN_MAIN】: where LW_DESIGN_NO = v_设计号
					PlnLengthwiseDsnMain pldm = new PlnLengthwiseDsnMain();
					pldm.setLw_design_no(v_dsn_no);
					this.getMapper(PlnLengthwiseDsnMainMapper.class).doDelete(pldm);

					// 删除 坯料设计订单组成表【PLN_DSN_ORDER_INFO】: where DESIGN_NO = v_设计号
					PlnDsnOrderInfo pdoid = new PlnDsnOrderInfo();
					pdoid.setDesign_no(v_dsn_no);
					this.getMapper(PlnDsnOrderInfoMapper.class).doDelete(pdoid);
				} else if ("DCL".equals(v_dsn_no.substring(0, 3))) {
					// 删除 开平拼料信息表【PLN_CUTTOLENGTH_DSN_MULTINFO】: where CL_DESIGN_NO = v_设计号
					PlnCuttolengthDsnMultinfo pldmd = new PlnCuttolengthDsnMultinfo();
					pldmd.setCl_design_no(v_dsn_no);
					this.getMapper(PlnCuttolengthDsnMultinfoMapper.class).doDelete(pldmd);

					// 删除 分条设计主表【PLN_CUTTOLENGTH_DSN_MAIN】: where CL_DESIGN_NO = v_设计号
					PlnCuttolengthDsnMain pldm = new PlnCuttolengthDsnMain();
					pldm.setCl_design_no(v_dsn_no);
					this.getMapper(PlnCuttolengthDsnMainMapper.class).doDelete(pldm);

					// 删除 坯料设计订单组成表【PLN_DSN_ORDER_INFO】: where DESIGN_NO = v_设计号
					PlnDsnOrderInfo pdoid = new PlnDsnOrderInfo();
					pdoid.setDesign_no(v_dsn_no);
					this.getMapper(PlnDsnOrderInfoMapper.class).doDelete(pdoid);
				} else if ("DAN".equals(v_dsn_no.substring(0, 3))) {
					// 删除 罩退坯料信息表
					this.getMapper(PlnAnnealDsnMultinfoMapper.class).doDelete(v_dsn_no);

					// 删除 罩退设计主表
					this.getMapper(PlnAnnealDsnMainMapper.class).doDelete(v_dsn_no);

					// 删除 坯料设计订单组成表【PLN_DSN_ORDER_INFO】: where DESIGN_NO = v_设计号
					PlnDsnOrderInfo pdoid = new PlnDsnOrderInfo();
					pdoid.setDesign_no(v_dsn_no);
					this.getMapper(PlnDsnOrderInfoMapper.class).doDelete(pdoid);
				} else if ("DSR".equals(v_dsn_no.substring(0, 3))) {
					// 删除平整坯料信息表
					this.getMapper(PlnSkinrollingDsnMultinfoMapper.class).doDelete(v_dsn_no);

					// 删除 平整设计主表
					this.getMapper(PlnSkinrollingDsnMainMapper.class).doDelete(v_dsn_no);

					// 删除 坯料设计订单组成表【PLN_DSN_ORDER_INFO】: where DESIGN_NO = v_设计号
					PlnDsnOrderInfo pdoid = new PlnDsnOrderInfo();
					pdoid.setDesign_no(v_dsn_no);
					this.getMapper(PlnDsnOrderInfoMapper.class).doDelete(pdoid);
				} else if ("DRL".equals(v_dsn_no.substring(0, 3))) {
					// 删除轧制坯料信息表
					this.getMapper(PlnRollingDsnMultinfoMapper.class).doDelete(v_dsn_no);

					// 删除 轧制设计主表
					this.getMapper(PlnRollingDsnMainMapper.class).doDelete(v_dsn_no);

					// 删除 坯料设计订单组成表【PLN_DSN_ORDER_INFO】: where DESIGN_NO = v_设计号
					PlnDsnOrderInfo pdoid = new PlnDsnOrderInfo();
					pdoid.setDesign_no(v_dsn_no);
					this.getMapper(PlnDsnOrderInfoMapper.class).doDelete(pdoid);
				}
			}
		}
	}

	/**
	 * 保存产线和机台代码
	 * 
	 * @param object_no_vt 虚拟物料号
	 * @param pline_code
	 * @param machine_code
	 * @param oci
	 * @throws Exception
	 */
	public void updatePline(CommonPage<PlnMaterielDetail> oci) throws Exception {
		List<PlnMaterielDetail> pmd = oci.getObjectList();
		try {
			for (PlnMaterielDetail pln : pmd) {
				this.getMapper(PlnMaterielDetailMapper.class).doUpdateMachine_code(pln);
			}
		} catch (Exception ex) {
			throw new Exception("保存机台信息失败!");
		}
	}
}
