/***文档注释***********************************************
 * 作者            ：syh
 * 创建日期     ：2018-05-31
 * 描述            ：横剪计划表
 * 注意事项     ：
 * 遗留BUG   ：
 * 修改日期     ：
 * 修改人员     ：
 * 修改内容     ：
 ***********************************************************/
package market.Mes.Cuttolength.Plan.impl;
import java.io.File;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.UnderlineStyle;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import market.Api.Lms.impl.LmsApiServiceImpl;
import market.Api.Mes.impl.MesApiCrCrossCuttingMServiceImpl;
import market.Api.Mes.impl.MesApiDesignInfoImpl;
import market.Api.Mes.impl.MesApiServiceImpl;
import market.Api.Mes.impl.ProcessPoint;
import market.Api.Mes.impl.Utils;
import market.Api.Mes.service.MesApiCrCrossCuttingMService;
import market.Api.Mes.service.MesApiService;
import market.Api.Qms.impl.QmsApiServiceImpl;
import market.Api.Qms.vo.JudgeResult;
import market.Com.impl.PbModelDbServiceImpl;
import market.Com.mapper.ComBaseInfoMapper;
import market.Com.mapper.ComBaseMachineMapper;
import market.Com.mapper.ComBasePlineMapper;
import market.Com.mapper.ComBaseSteelMapper;
import market.Com.mapper.PbModelDbMapper;
import market.Com.vo.ComBaseCbYdd;
import market.Com.vo.ComBaseInfo;
import market.Com.vo.ComBaseMachine;
import market.Com.vo.ComBasePline;
import market.Com.vo.ComBaseSteel;
import market.Com.vo.CommonPage;
import market.Com.vo.ResultModel;
import market.Lms.Warehouse.mapper.YdmProductDetailMapper;
import market.Lms.Warehouse.service.YdmProductInlistService;
import market.Lms.Warehouse.vo.YdmProductDetail;
import market.Mes.Cuttolength.Design.mapper.PlnCuttolengthDsnMainMapper;
import market.Mes.Cuttolength.Design.vo.PlnCuttolengthDsnMain;
import market.Mes.Cuttolength.Design.vo.PlnCuttolengthDsnMainSum;
import market.Mes.Cuttolength.Plan.mapper.MesCrCrossCuttingWgtMapper;
import market.Mes.Cuttolength.Plan.mapper.PlnClPlanStatisticMapper;
import market.Mes.Cuttolength.Plan.mapper.PlnCuttolengthPlanDetailMapper;
import market.Mes.Cuttolength.Plan.mapper.PlnCuttolengthPlanMapper;
import market.Mes.Cuttolength.Plan.service.PlnCuttolengthPlanService;
import market.Mes.Cuttolength.Plan.vo.CommentDetialAndCuttD;
import market.Mes.Cuttolength.Plan.vo.MesCrCrossCuttingWgt;
import market.Mes.Cuttolength.Plan.vo.PlnClPlanStatistic;
import market.Mes.Cuttolength.Plan.vo.PlnCuttolengthPlan;
import market.Mes.Cuttolength.Plan.vo.PlnCuttolengthPlanDetail;
import market.Mes.Lengthwise.Design.mapper.PlnDsnOrderInfoMapper;
import market.Mes.Lengthwise.Design.vo.PlnDsnOrderInfo;
import market.Mes.Lengthwise.Plan.mapper.MesCrCrossCuttingDMapper;
import market.Mes.Lengthwise.Plan.mapper.MesCrCrossCuttingMMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnMaterielDetailMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnProcessPlanMapper;
import market.Mes.Lengthwise.Plan.vo.MesCrCrossCuttingD;
import market.Mes.Lengthwise.Plan.vo.MesCrCrossCuttingM;
import market.Mes.Lengthwise.Plan.vo.PlnMaterielDetail;
import market.Mes.Lengthwise.Plan.vo.PlnProcessPlan;
import market.Mes.MaterielTrack.vo.PrcMaterielProcess;
import market.Mes.MaterielTrack.vo.PrcMaterielRelation;
import market.Mes.Opr.mapper.MesOprLogMapper;
import market.Mes.Opr.vo.MesOprLog;
import market.Mes.OrderManager.Plan.impl.PlnProdorderStatisticServiceImpl;
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.Shift.mapper.MesShiftMMapper;
import market.Mes.Shift.vo.MesShiftM;
import market.Mes.Tpm.mapper.MesTpmPrintLogMapper;
import market.Mes.Tpm.vo.MesTpmPrintLog;
import market.Mes.anneal.mapper.MesCrAnnealMMapper;
import market.Mes.anneal.vo.MesJihuaZhi;
import market.Mes.util.DateUtil;
import market.Qms.qcm.service.impl.QcmJhySampleConsignDItemServiceImpl;
import market.Qms.qcm.vo.QcmJhySampleFromPlan;
import market.Slm.FundManagement.service.SlmFundFirstDetailService;

import org.apache.commons.collections.CollectionUtils;
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="PlnCuttolengthPlanService")
public class PlnCuttolengthPlanServiceImpl extends BaseServiceImpl<PlnCuttolengthPlan,Object> implements PlnCuttolengthPlanService {

	
	
	/**
	 * 3mm作业指示
	 * @param oci
	 * object:
	 * material_no:投料卷号
	 * materailcoilno：原始卷号
	 * steel_name:牌号
	 * order_no:订单号
	 * reciver_unit_name:客户名称
	 * memo1:传机台代码
	 * startTime:开始时间
	 * endTime:结束时间
	 * @return
	 */
	public ResultModel doQuery3mmWeb(CommonPage<MesJihuaZhi> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			List<HashMap> lpav=this.getMapper(MesCrCrossCuttingMMapper.class).doQueryWeb_jihuazhi(oci.getObject(),oci.getMemo1(),oci.getMemo2(),oci.getStartTime(),oci.getEndTime(),oci.getMemo3());
			rm.setData(lpav);
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	
	/***
	 * 动作处理-上料按钮     insertmesCrCrossCuttingM
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doPlnCuttInsWeb(String vPlanNo, String vObjectNoVt,
			String vMaterialNo, String vMchCode, String vWrkGrp, String vOprName)
					throws Exception {
		ResultModel r=new ResultModel();
		Date now = new Date();
		String userId = (String) this.getSession().getAttribute(HomeService.SESSION_USER_ID);
		vOprName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprName==null){
			vOprName="";
		}
		
		String v_ret = ""; // 返回到前端的错误提示信息
		Integer v_cnt;
		String v_process_no;
		DateFormat df = new SimpleDateFormat("HH:mm:ss");
		DateFormat dftwo = new SimpleDateFormat("yyyy-MM-dd");
		String vCurrTime =null;// 获取数据库当前的系统时刻
		String vDate = null;
		String vOrd = null;
		String vGrp = null;
		CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
		
		// 1 验证前端传入的班组代码有效性
		if (vWrkGrp == null
				|| ((!vWrkGrp.equals("1")) && (!vWrkGrp.equals("2")) && (!vWrkGrp
						.equals("3")))) {
			throw new Exception("班组代码：" + vWrkGrp + "无效，\n只能是 1（甲班）或2（乙班）或3（丙班）！请选择正确的班组，重新登录系统!");
		}
		// 2 验证横剪作业计划主记录存在
		PlnCuttolengthPlan pcp=new PlnCuttolengthPlan();
		pcp.setMachine_code(vMchCode);
		pcp.setCl_plan_no(vPlanNo);
		int count = this.getMapper(PlnCuttolengthPlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+vMchCode+"\n作业计划号："+vPlanNo+"\n作业计划主记录不存在！");
		};
		
		// 3 验证横剪作业计划明细记录存在
		PlnCuttolengthPlanDetail pcpd=new PlnCuttolengthPlanDetail();
		pcpd.setMachine_code(vMchCode);
		pcpd.setCl_plan_no(vPlanNo);
		pcpd.setObject_no_vt(vObjectNoVt);
		pcpd.setObject_no(vMaterialNo);
		int count2 = this.getMapper(PlnCuttolengthPlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+vMchCode+"\n作业计划号："+vPlanNo+"\n虚拟卷号："+vObjectNoVt+""
					+ "\n原料卷号："+vMaterialNo+"\n作业计划明细记录不存在！");
		}
		PlnCuttolengthPlanDetail cuttdel = new PlnCuttolengthPlanDetail();
		cuttdel.setMachine_code(vMchCode);
		cuttdel.setCl_plan_no(vPlanNo);
		cuttdel.setObject_no_vt(vObjectNoVt);
		cuttdel.setObject_no(vMaterialNo);
		List<PlnCuttolengthPlanDetail> v_rec_plan_detail = this.getMapper(
				PlnCuttolengthPlanDetailMapper.class).findWithCondition(
						cuttdel, null, null, 0, 0);

		// 4 验证虚拟物料表中，原料卷计划信息存在
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(vObjectNoVt);
		int count3 = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if (count3<=0) {
			throw new Exception("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
		}
		PlnMaterielDetail tYdm = new PlnMaterielDetail();
		tYdm.setObject_no_vt(vObjectNoVt);
		List<PlnMaterielDetail> v_rec_materiel_detail = this.getBean(
				PlnMaterielDetailMapper.class).findWithCondition(tYdm, null,
						null, 0, 0);

		// 5 验证原料卷号库存明细记录存在
		YdmProductDetail tYdm2 = new YdmProductDetail();
		tYdm2.setCoilno(vMaterialNo);
		v_cnt = this.getMapper(YdmProductDetailMapper.class).count(tYdm2);
		if (v_cnt <= 0) {
			throw new Exception("原料卷号：" + vMaterialNo + "库存明细记录不存在！");
		}

		// （6）、验证原料卷号库存明细记录为“在库”状态
		YdmProductDetail tYdm3 = new YdmProductDetail();
		tYdm3.setCoilno(vMaterialNo);
		List<YdmProductDetail>  v_rec_product_detail = this.getMapper(
				YdmProductDetailMapper.class).findWithCondition(tYdm3,
						null, null, 0, 0);
		if (v_rec_product_detail.get(0).getState()==null
				|| (!v_rec_product_detail.get(0).getState().equals("0"))) {
			throw new Exception("原料卷号：" + vMaterialNo + "，当前不是“在库”状态！");
		}

		// （7）、验证指定的计划，还未创建横剪作业主实绩
		MesCrCrossCuttingM mCross = new MesCrCrossCuttingM();
		mCross.setMachine_code(vMchCode);
		mCross.setSchedule_no(vPlanNo);
		mCross.setMaterial_no_vt(vObjectNoVt);
		mCross.setMaterial_no(vMaterialNo);
		v_cnt = this.getBean(MesCrCrossCuttingMMapper.class).count(mCross);
		if (v_cnt > 0) {
			throw new Exception("原料卷号：" + vMaterialNo + "，当前存在开平作业主实绩！");
		}

		//2018-11-29 只有是已下发状态的钢卷才能下发
		if(v_rec_plan_detail!=null && v_rec_plan_detail.size()>0){
			if(!"5BCL02".equals(v_rec_plan_detail.get(0).getStatus())){
				throw new Exception("当前状态{"+v_rec_plan_detail.get(0).getStatus()+"}不为已下发");
			}
		}
		
		//准对捆包情况的处理
		if(v_rec_plan_detail.get(0).getIs_main_plan()!=null && v_rec_plan_detail.get(0).getIs_main_plan().intValue()==1){
			PlnCuttolengthPlanDetail pcpp=new PlnCuttolengthPlanDetail();
			pcpp.setCl_plan_no(vPlanNo);
			pcpp.setMachine_code(vMchCode);
			pcpp.setIs_bales(1);
			List<PlnCuttolengthPlanDetail> list_pcpp = this.getMapper(PlnCuttolengthPlanDetailMapper.class).findWithCondition(pcpp, "", "", 0, 0);
			for(PlnCuttolengthPlanDetail pcplen:list_pcpp){
				this.getBean(PlnCuttolengthPlanServiceImpl.class).doPlnCuttInsWebMany(pcplen.getCl_plan_no(),
						pcplen.getObject_no_vt(),pcplen.getObject_no(), 
						pcpp.getMachine_code(), vWrkGrp, vOprName);
			}
			r.setState("200");
			r.setMsgInfo("上料成功!");
			return r;
		}
		
		
		
		// （8）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		if("200".equals(rmDb.getState())){
			vCurrTime=rmDb.getData().toString().substring(11);
			if (vCurrTime.compareTo(DateUtil.NBeginTime)>-1&&vCurrTime.compareTo(DateUtil.BeginTime)<0) {
				vDate = rmDb.getData().toString().substring(0,10);
				vOrd = "1";
			}else if(vCurrTime.compareTo(DateUtil.BeginTime)>-1&&vCurrTime.compareTo(DateUtil.EndTime)<0) {
				vDate =rmDb.getData().toString().substring(0,10);
				vOrd = "2";
			}
			else if(vCurrTime.compareTo(DateUtil.EndTime)>=0 && vCurrTime.compareTo(DateUtil.NEndTime)<=0) {
				vOrd = "1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date = formatYmd.parse(rmDb.getData().toString().substring(0,10));
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
    	        vDate=formatYmd.format(c.getTime());
				vOrd = "1";
			}
//			if (vCurrTime.compareTo("00:00:00")>-1&&vCurrTime.compareTo("08:00:00")<0) {
//				vDate = rmDb.getData().toString().substring(0,10);
//				vOrd = "1";
//			}else if(vCurrTime.compareTo("08:00:00")>-1&&vCurrTime.compareTo("20:00:00")<0) {
//				vDate =rmDb.getData().toString().substring(0,10);
//				vOrd = "2";
//			}
//			else if(vCurrTime.compareTo("20:00:00")>=0 && vCurrTime.compareTo("23:59:59")<=0) {
//				vOrd = "1";
//				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
//				Date date = formatYmd.parse(rmDb.getData().toString().substring(0,10));
//				Calendar c = Calendar.getInstance();  
//				c.setTime(date);  
//				c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
//				vDate=formatYmd.format(c.getTime());
//				vOrd = "1";
//			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}

		MesShiftM Mesm = new MesShiftM();
		Mesm.setMachine_code(vMchCode);
		Mesm.setWrk_date(vDate);
		Mesm.setWrk_ord(vOrd);
		v_cnt = this.getMapper(MesShiftMMapper.class).count(Mesm);
		// 获取班组(暂无交接班记录，则使用前端传入的班组代码)
		// 否则获取 交接班记录 (newlsitmMesm)中的班组
		if (v_cnt <= 0) {
			vGrp = vWrkGrp;
		} else {
			List<MesShiftM> newlsitmMesm = this.getMapper(
					MesShiftMMapper.class).findWithCondition(Mesm, null,
							null, 0, 0);
			vGrp = newlsitmMesm.get(0).getWrk_grp();
		}

		// (9) 生产处理号PROCESS_NO的生成规则
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(vMchCode);
		v_cnt = this.getMapper(ComBaseMachineMapper.class).count(machine);
		if (v_cnt <= 0) {
			throw new Exception("机台代码：" + vMchCode + "，\n机台基础信息不存在！");
		}
		// 9.1 获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
		ComBaseMachine machine2 = new ComBaseMachine();
		machine2.setMachine_code(vMchCode);
		List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class)
				.find(machine2, 0, 0);
		v_process_no=lcbm.get(0).getMachine_mark();
		if (v_process_no == null) {
			throw new Exception("机台代码：" + vMchCode + "\n设备编号未配置，无法创建作业记录号");
		}
		// 9.2 大 写字母'K' + 6位日期（YYMMDD，取数据库时间） + 2位纵剪设备编号（不足为前面补0）
		// 补零
		SimpleDateFormat formatY3 = new SimpleDateFormat("yyMMdd");
		v_process_no = "K" + formatY3.format(new Date())+lpad(v_process_no, 2, "0");
		v_cnt = this.getMapper(MesCrCrossCuttingMMapper.class).doquery(v_process_no);
		if (v_cnt == null) {
			v_cnt = 1;
		}
		//v_process_no = v_process_no + lpad(v_cnt.toString(), 3, "0");
		v_process_no = v_process_no + lpad(v_cnt.toString(), 3, "0");

		// （10）  --（10）、创建横剪/开平主实绩记录																																							
		// --(10.1)、原料卷计划规格、牌号等信息来源于 pln_materiel_detail 表																																							
		//--(10.2)、原料卷实际规格、牌号等信息来源于 ydm_product_detail 表	
		this.getMapper(MesCrCrossCuttingMMapper.class).insertmesCrCrossCuttingM(v_rec_materiel_detail.get(0),  v_rec_product_detail.get(0),
		   vMchCode, vOprName, vPlanNo, vObjectNoVt, vMaterialNo, v_process_no, v_rec_plan_detail.get(0),  vDate, vOrd, vGrp);
		
		//11调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）
		MesCrCrossCuttingM  mcsm=new MesCrCrossCuttingM();
		mcsm.setMachine_code(vMchCode);//机台号
		mcsm.setSchedule_no(vPlanNo);//作业计划号
		mcsm.setMaterial_no(vMaterialNo);//投料卷号
		mcsm.setMaterial_no_vt(vObjectNoVt);//虚拟卷号 
		mcsm.setInner_seq(Long.valueOf(v_rec_plan_detail.get(0).getCl_seq()));
		List<MesCrCrossCuttingM> lmcsm=new ArrayList<MesCrCrossCuttingM>();
		
		
		//时间
		SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");//设置日期格式
	    String date = dfs.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
	    mcsm.setMemo(date);
	    lmcsm.add(mcsm);
	    this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMAdd(lmcsm); 
		
	   //12.调用物流模块接口，执行原料卷生产投料出库相关操作（接口由物流模块提供）；
	    v_rec_product_detail.get(0).setMemo(date);
		cp.setObject(v_rec_product_detail.get(0));
		this.getBean(LmsApiServiceImpl.class).doOutStorage(cp);
		
		try{
			this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(vMaterialNo,true);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
		if ("1".equals(isOpen)) {
		
			// 记录成本异动点：20230811刘侣
			YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).doFind(vMaterialNo, null);
			ComBaseCbYdd cd = new ComBaseCbYdd();
			cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
			cd.setInstDisp("01");
			cd.setDataTypeIdx("O");
			// 当前产线：
			String currentMachine = ypd.getCoilno().contains("S") ? "YTSX" : ypd.getCoilno().contains("L") ? "YTZZ" : ypd.getCoilno().contains("P") ? "YTPZ" : ypd.getCoilno().contains("T") ? "YTTH" : ypd.getCoilno().contains("K") ? "YTHJ" : ypd.getCoilno().contains("F") ? "YTZJ" : "YT1";
			cd.setLocNo(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setInvQtyUnit("块");
			cd.setInvWidth(ypd.getWidth() != null ? String.valueOf(ypd.getWidth()) : "0");
			cd.setCreateId(userId);
			cd.setActivityId("41A");
			cd.setInvLength(ypd.getLength() != null ? String.valueOf(ypd.getLength()) : "0");
			cd.setManageip(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setProdName(ypd.getProd_name());
			cd.setInvThick(ypd.getThick() != null ? String.valueOf(ypd.getThick()) : "0");
			
			
			String prevcoil = ypd.getCoilno();
			// 上道产线：
			String prevMachine = prevcoil.contains("S") ? "YTSX" : prevcoil.contains("L") ? "YTZZ" : prevcoil.contains("P") ? "YTPZ" : prevcoil.contains("T") ? "YTTH" : prevcoil.contains("K") ? "YTHJ" : prevcoil.contains("F") ? "YTZJ" : "YT1";
			cd.setRefnoA("YT1".equals(prevMachine) ? ypd.getMaterailcoilno() : prevcoil); // 投料卷号
			cd.setSysId("IA");
			cd.setOrderItem(ypd.getOrderno());
			cd.setCrntMill(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setBeTransUnit("t");
			cd.setExecJobFunc("N");
			ComBaseSteel cbs = this.getMapper(ComBaseSteelMapper.class).findById(ypd.getSteelcode());
			if (cbs != null) {
				cd.setAlloyNo(cbs.getSteel_name()); // 牌号
			}
			
			cd.setAcctDate(new SimpleDateFormat("yyyyMMdd").format(now));
			cd.setLastMill(prevMachine); // 填上道工序产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setBeTransWgt(ypd.getFactweight() != null ? ypd.getFactweight() / 1000 : ypd.getFactweight());
			cd.setProdTypeNo("CTR");
			cd.setAppId("优特钢横剪上料");
			cd.setInvId("YT1".equals(currentMachine) ? ypd.getMaterailcoilno() : ypd.getCoilno());
			cd.setInvQty("1");

			// setSrcFac根据卷的物料属性去判断：20231031刘侣
			cd.setSrcFac("507101".equals(ypd.getObject_attr()) ? "1" : "3");
			
			cd.setGrade("40740801".equals(ypd.getJudgeresult()) ? "1" : "1"); // 正品　1　协议　3　次品　5
			cd.setProdClassNo("H");
				
			// 存入表：1、上料一抛：原料转库（47）（原料上料准备生产时抛送）
			cd.setActivityId("55A");
			cd.setExecJobFunc("N");
			cd.setDataTypeIdx("O");
			cd.setProdTypeNo("YT1".equals(prevMachine) && cd.getInvId().startsWith("L") ? "CCR" : "YT1".equals(prevMachine) ? "HCR" : "CTR");
			cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
			cd.setCrntMill(prevMachine); // 填上道产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setManageip(prevMachine); // 填上道产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setLocNo(prevMachine); // 填上道产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
//			String currentMName = ypd.getCoilno().contains("S") ? "酸洗" : ypd.getCoilno().contains("L") ? "冷轧" : ypd.getCoilno().contains("P") ? "平整" : ypd.getCoilno().contains("T") ? "退火" : ypd.getCoilno().contains("K") ? "横剪" : ypd.getCoilno().contains("F") ? "分条" : "原料";
			String prevMName = prevcoil.contains("S") ? "酸洗" : prevcoil.contains("L") ? "冷轧" : prevcoil.contains("P") ? "平整" : prevcoil.contains("T") ? "退火" : prevcoil.contains("K") ? "开平" : prevcoil.contains("F") ? "分条" : "原料";
			cd.setAppId("优特" + prevMName + "转库");
			
			// 一次结算后第一次生产点上料的时候，不抛 转库和接收原料  改抛 12AB
			// 该卷是否刚刚一次结算完：可以根据提单里是否有这卷的一次结算数据进行判断：
//			int isYcJs = this.getMapper(YdmProductDetailMapper.class).isHasYcJs(ypd.getCoilno());
//			if (isYcJs <= 0) {
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypd.getMaterailcoilno());
//			}
			
			// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
			// 对已有数据进行修改：
			cd.setDataTypeIdx("N");
//			cd.setProdTypeNo("CTR");
			cd.setManageip("YTHJ");
			cd.setLocNo("YTHJ");
			cd.setAppId("开平接收原料");
			
			// 20231130刘侣
//			if (isYcJs > 0) {
//				cd.setActivityId("12AB");
//				cd.setAppId("来料加工");
//			}
			// end
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypd.getMaterailcoilno());
			// 三抛：酸洗上料（41，开始生产
			cd.setActivityId("41A");
			cd.setDataTypeIdx("O");
			cd.setAppId("开平上料");
			cd.setLastMill("YTHJ");
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypd.getMaterailcoilno());
			// end
		}
		
		r.setState("200");
		r.setMsgInfo("上料成功!");
		return r;
	}

	
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doPlnCuttInsWebMany(String vPlanNo, String vObjectNoVt,
			String vMaterialNo, String vMchCode, String vWrkGrp, String vOprName)
					throws Exception {
		ResultModel r=new ResultModel();
		
		vOprName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprName==null){
			vOprName="";
		}
		
		String v_ret = ""; // 返回到前端的错误提示信息
		Integer v_cnt;
		String v_process_no;
		DateFormat df = new SimpleDateFormat("HH:mm:ss");
		DateFormat dftwo = new SimpleDateFormat("yyyy-MM-dd");
		String vCurrTime =null;// 获取数据库当前的系统时刻
		String vDate = null;
		String vOrd = null;
		String vGrp = null;
		CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
		
		// 1 验证前端传入的班组代码有效性
		if (vWrkGrp == null
				|| ((!vWrkGrp.equals("1")) && (!vWrkGrp.equals("2")) && (!vWrkGrp
						.equals("3")))) {
			throw new Exception("班组代码：" + vWrkGrp + "无效，\n只能是 1（甲班）或2（乙班）或3（丙班）！请选择正确的班组，重新登录系统!");
		}
		// 2 验证横剪作业计划主记录存在
		PlnCuttolengthPlan pcp=new PlnCuttolengthPlan();
		pcp.setMachine_code(vMchCode);
		pcp.setCl_plan_no(vPlanNo);
		int count = this.getMapper(PlnCuttolengthPlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+vMchCode+"\n作业计划号："+vPlanNo+"\n作业计划主记录不存在！");
		};
		
		// 3 验证横剪作业计划明细记录存在
		PlnCuttolengthPlanDetail pcpd=new PlnCuttolengthPlanDetail();
		pcpd.setMachine_code(vMchCode);
		pcpd.setCl_plan_no(vPlanNo);
		pcpd.setObject_no_vt(vObjectNoVt);
		pcpd.setObject_no(vMaterialNo);
		int count2 = this.getMapper(PlnCuttolengthPlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+vMchCode+"\n作业计划号："+vPlanNo+"\n虚拟卷号："+vObjectNoVt+""
					+ "\n原料卷号："+vMaterialNo+"\n作业计划明细记录不存在！");
		}
		PlnCuttolengthPlanDetail cuttdel = new PlnCuttolengthPlanDetail();
		cuttdel.setMachine_code(vMchCode);
		cuttdel.setCl_plan_no(vPlanNo);
		cuttdel.setObject_no_vt(vObjectNoVt);
		cuttdel.setObject_no(vMaterialNo);
		List<PlnCuttolengthPlanDetail> v_rec_plan_detail = this.getMapper(
				PlnCuttolengthPlanDetailMapper.class).findWithCondition(
						cuttdel, null, null, 0, 0);

		// 4 验证虚拟物料表中，原料卷计划信息存在
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(vObjectNoVt);
		int count3 = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if (count3<=0) {
			throw new Exception("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
		}
		PlnMaterielDetail tYdm = new PlnMaterielDetail();
		tYdm.setObject_no_vt(vObjectNoVt);
		List<PlnMaterielDetail> v_rec_materiel_detail = this.getBean(
				PlnMaterielDetailMapper.class).findWithCondition(tYdm, null,
						null, 0, 0);

		// 5 验证原料卷号库存明细记录存在
		YdmProductDetail tYdm2 = new YdmProductDetail();
		tYdm2.setCoilno(vMaterialNo);
		v_cnt = this.getMapper(YdmProductDetailMapper.class).count(tYdm2);
		if (v_cnt <= 0) {
			throw new Exception("原料卷号：" + vMaterialNo + "库存明细记录不存在！");
		}

		// （6）、验证原料卷号库存明细记录为“在库”状态
		YdmProductDetail tYdm3 = new YdmProductDetail();
		tYdm3.setCoilno(vMaterialNo);
		List<YdmProductDetail>  v_rec_product_detail = this.getMapper(
				YdmProductDetailMapper.class).findWithCondition(tYdm3,
						null, null, 0, 0);
		if (v_rec_product_detail.get(0).getState()==null
				|| (!v_rec_product_detail.get(0).getState().equals("0"))) {
			throw new Exception("原料卷号：" + vMaterialNo + "，当前不是“在库”状态！");
		}

		// （7）、验证指定的计划，还未创建横剪作业主实绩
		MesCrCrossCuttingM mCross = new MesCrCrossCuttingM();
		mCross.setMachine_code(vMchCode);
		mCross.setSchedule_no(vPlanNo);
		mCross.setMaterial_no_vt(vObjectNoVt);
		mCross.setMaterial_no(vMaterialNo);
		v_cnt = this.getBean(MesCrCrossCuttingMMapper.class).count(mCross);
		if (v_cnt > 0) {
			throw new Exception("原料卷号：" + vMaterialNo + "，当前存在开平作业主实绩！");
		}

		//2018-11-29 只有是已下发状态的钢卷才能下发
		if(v_rec_plan_detail!=null && v_rec_plan_detail.size()>0){
			if(!"5BCL02".equals(v_rec_plan_detail.get(0).getStatus())){
				throw new Exception("当前状态{"+v_rec_plan_detail.get(0).getStatus()+"}不为已下发");
			}
		}
		
	
		
		
		
		// （8）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		if("200".equals(rmDb.getState())){
			vCurrTime=rmDb.getData().toString().substring(11);
			if (vCurrTime.compareTo(DateUtil.NBeginTime)>-1&&vCurrTime.compareTo(DateUtil.BeginTime)<0) {
				vDate = rmDb.getData().toString().substring(0,10);
				vOrd = "1";
			}else if(vCurrTime.compareTo(DateUtil.BeginTime)>-1&&vCurrTime.compareTo(DateUtil.EndTime)<0) {
				vDate =rmDb.getData().toString().substring(0,10);
				vOrd = "2";
			}
			else if(vCurrTime.compareTo(DateUtil.EndTime)>=0 && vCurrTime.compareTo(DateUtil.NEndTime)<=0) {
				vOrd = "1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date = formatYmd.parse(rmDb.getData().toString().substring(0,10));
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
    	        vDate=formatYmd.format(c.getTime());
				vOrd = "1";
			}
//			if (vCurrTime.compareTo("00:00:00")>-1&&vCurrTime.compareTo("08:00:00")<0) {
//				vDate = rmDb.getData().toString().substring(0,10);
//				vOrd = "1";
//			}else if(vCurrTime.compareTo("08:00:00")>-1&&vCurrTime.compareTo("20:00:00")<0) {
//				vDate =rmDb.getData().toString().substring(0,10);
//				vOrd = "2";
//			}
//			else if(vCurrTime.compareTo("20:00:00")>=0 && vCurrTime.compareTo("23:59:59")<=0) {
//				vOrd = "1";
//				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
//				Date date = formatYmd.parse(rmDb.getData().toString().substring(0,10));
//				Calendar c = Calendar.getInstance();  
//				c.setTime(date);  
//				c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
//				vDate=formatYmd.format(c.getTime());
//				vOrd = "1";
//			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}

		MesShiftM Mesm = new MesShiftM();
		Mesm.setMachine_code(vMchCode);
		Mesm.setWrk_date(vDate);
		Mesm.setWrk_ord(vOrd);
		v_cnt = this.getMapper(MesShiftMMapper.class).count(Mesm);
		// 获取班组(暂无交接班记录，则使用前端传入的班组代码)
		// 否则获取 交接班记录 (newlsitmMesm)中的班组
		if (v_cnt <= 0) {
			vGrp = vWrkGrp;
		} else {
			List<MesShiftM> newlsitmMesm = this.getMapper(
					MesShiftMMapper.class).findWithCondition(Mesm, null,
							null, 0, 0);
			vGrp = newlsitmMesm.get(0).getWrk_grp();
		}

		// (9) 生产处理号PROCESS_NO的生成规则
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(vMchCode);
		v_cnt = this.getMapper(ComBaseMachineMapper.class).count(machine);
		if (v_cnt <= 0) {
			throw new Exception("机台代码：" + vMchCode + "，\n机台基础信息不存在！");
		}
		// 9.1 获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
		ComBaseMachine machine2 = new ComBaseMachine();
		machine2.setMachine_code(vMchCode);
		List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class)
				.find(machine2, 0, 0);
		v_process_no=lcbm.get(0).getMachine_mark();
		if (v_process_no == null) {
			throw new Exception("机台代码：" + vMchCode + "\n设备编号未配置，无法创建作业记录号");
		}
		// 9.2 大 写字母'K' + 6位日期（YYMMDD，取数据库时间） + 2位纵剪设备编号（不足为前面补0）
		// 补零
		SimpleDateFormat formatY3 = new SimpleDateFormat("yyMMdd");
		v_process_no = "K" + formatY3.format(new Date())+lpad(v_process_no, 2, "0");
		v_cnt = this.getMapper(MesCrCrossCuttingMMapper.class).doquery(v_process_no);
		if (v_cnt == null) {
			v_cnt = 1;
		}
		//v_process_no = v_process_no + lpad(v_cnt.toString(), 3, "0");
		v_process_no = v_process_no + lpad(v_cnt.toString(), 3, "0");

		// （10）  --（10）、创建横剪/开平主实绩记录																																							
		// --(10.1)、原料卷计划规格、牌号等信息来源于 pln_materiel_detail 表																																							
		//--(10.2)、原料卷实际规格、牌号等信息来源于 ydm_product_detail 表	
		this.getMapper(MesCrCrossCuttingMMapper.class).insertmesCrCrossCuttingM(v_rec_materiel_detail.get(0),  v_rec_product_detail.get(0),
		   vMchCode, vOprName, vPlanNo, vObjectNoVt, vMaterialNo, v_process_no, v_rec_plan_detail.get(0),  vDate, vOrd, vGrp);
		
		//11调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）
		MesCrCrossCuttingM  mcsm=new MesCrCrossCuttingM();
		mcsm.setMachine_code(vMchCode);//机台号
		mcsm.setSchedule_no(vPlanNo);//作业计划号
		mcsm.setMaterial_no(vMaterialNo);//投料卷号
		mcsm.setMaterial_no_vt(vObjectNoVt);//虚拟卷号 
		mcsm.setInner_seq(Long.valueOf(v_rec_plan_detail.get(0).getCl_seq()));
		List<MesCrCrossCuttingM> lmcsm=new ArrayList<MesCrCrossCuttingM>();
		
		
		//时间
		SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");//设置日期格式
	    String date = dfs.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
	    mcsm.setMemo(date);
	    lmcsm.add(mcsm);
	    this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMAdd(lmcsm); 
		
	   //12.调用物流模块接口，执行原料卷生产投料出库相关操作（接口由物流模块提供）；
	    v_rec_product_detail.get(0).setMemo(date);
		cp.setObject(v_rec_product_detail.get(0));
		this.getBean(LmsApiServiceImpl.class).doOutStorage(cp);
		
		try{
			this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(vMaterialNo,true);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		r.setState("200");
		r.setMsgInfo("上料成功!");
		return r;
	}
	
	
	
	
	
	
	
	
	/**
	 * 动作处理 -恢复计划    deleteByProcessNo
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doUpdateWeb(String vPlanNo, String vObjectNoVt,
			String vMaterialNo, String vMchCode, String vOprName)
					throws Exception {
		ResultModel r=new ResultModel();
		Date now = new Date();
		String userId = (String) this.getSession().getAttribute(HomeService.SESSION_USER_ID);
		vOprName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprName==null){
			vOprName="";
		}
		
		String v_ret = "";
		Integer v_cnt;
		CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
		
		// 1)、验证横剪/开平作业计划主记录存在
		String ifplan = ifplan(vMchCode, vPlanNo);
		if (isEmpty(ifplan) != null) {
			throw new Exception(ifplan);
		}
		// 2）、验证横剪/开平作业计划明细记录存在
		String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(ifplanDetail) != null) {
			throw new Exception(ifplanDetail);
		}
//		PlnCuttolengthPlanDetail pcpd = new PlnCuttolengthPlanDetail();
//		pcpd.setMachine_code(vMchCode);
//		pcpd.setCl_plan_no(vPlanNo);
//		pcpd.setObject_no_vt(vObjectNoVt);
//		pcpd.setObject_no(vMaterialNo);
//	    List<PlnCuttolengthPlanDetail> lppd = this.getBean(PlnCuttolengthPlanDetailMapper.class).find(pcpd, 0, 0);
//	    //获取开平序号
//		int cl_seq = lppd.get(0).getCl_seq();
		
		// 3 验证虚拟物料表中，原料卷计划信息存在
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(vObjectNoVt);
		int count = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if(count<=0){
			throw new Exception("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
		}
		
		// 4 验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
		if (isEmpty(isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo) )!= null) {
			throw new Exception(isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo));
		}
		MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
		cuttingM.setMachine_code(vMchCode);
		cuttingM.setSchedule_no(vPlanNo);
		cuttingM.setMaterial_no_vt(vObjectNoVt);
		cuttingM.setMaterial_no(vMaterialNo);
		List<MesCrCrossCuttingM> v_rec_ccm = this.getBean(
				MesCrCrossCuttingMMapper.class).findWithCondition(cuttingM,
						null, null, 0, 0);
		if (v_rec_ccm.get(0).getHand_over_status() != null
				&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
			throw new Exception("原料卷号：" + vMaterialNo + "当前已生产交工，不能恢复计划！"+"\n"
					+"可取消交工，并删除所有板垛记录后，再进行此操作！");
		}
		// 5.验证原料卷，当前未生成板垛实绩
		MesCrCrossCuttingD crcrD = new MesCrCrossCuttingD();
		crcrD.setProcess_no(v_rec_ccm.get(0).getProcess_no());
		v_cnt = this.getBean(MesCrCrossCuttingDMapper.class).count(crcrD);
		if (v_cnt > 0) {
			throw new Exception("原料卷号：" + vMaterialNo + "已生成板垛实绩，不能恢复计划"+"\n"
		+"可删除所有板垛记录后，再进行此操作！");
		}

		
		//准对捆包情况的处理
		if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
			PlnCuttolengthPlanDetail pcpp=new PlnCuttolengthPlanDetail();
			pcpp.setCl_plan_no(vPlanNo);
			pcpp.setMachine_code(vMchCode);
			pcpp.setIs_bales(1);
			List<PlnCuttolengthPlanDetail> list_pcpp = this.getMapper(PlnCuttolengthPlanDetailMapper.class).findWithCondition(pcpp, "", "", 0, 0);
			for(PlnCuttolengthPlanDetail pcplen:list_pcpp){
				this.getBean(PlnCuttolengthPlanServiceImpl.class).doUpdateWebmany(pcplen.getCl_plan_no(), pcplen.getObject_no_vt(),
						pcplen.getObject_no(), pcplen.getMachine_code(), vOprName);
			}
			r.setState("200");
			r.setMsgInfo("恢复计划成功!");
			return r;
		}
		
		//6.调用生产管理接口，验证是否能执行相关操作，如果不满足条件，返回错误信息到前端
		this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMCancelValid(v_rec_ccm);

//		List<MesCrCrossCuttingM> lmcsm=new ArrayList<MesCrCrossCuttingM>();
//		lmcsm.add(cuttingM);
		//注意 ？？
		//this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMAddValid(v_rec_ccm);

		//7.调用物流模块接口，验证原料卷可撤销生产出库操作
		YdmProductDetail ypdu=new YdmProductDetail();
		ypdu.setCoilno(vMaterialNo);
		List<YdmProductDetail > listProductDetail=this.getMapper(YdmProductDetailMapper.class).findWithCondition(ypdu, null, null, 0, 0);
		cp.setObject(ypdu);
		r = this.getBean(LmsApiServiceImpl.class).doDepend(cp);
		if("500".equals(r.getState())){
			throw new Exception(r.getMsgInfo());
		}
		//8、删除横剪/开平实绩主记录
		this.getMapper(MesCrCrossCuttingMMapper.class).deleteByProcessNo(v_rec_ccm.get(0).getProcess_no());

		//9.调用生产管理接口，执行业计划状态、物料进程状态相关操作
		// 9.1调用生产管理接口，验证作业计划状态能执行此操作，否则，返回错误信息并提示
		List<MesCrCrossCuttingM> lmcsmq=new ArrayList<MesCrCrossCuttingM>();
		cuttingM.setInner_seq(Long.valueOf(v_rec_ccm.get(0).getInner_seq()));
		lmcsmq.add(cuttingM);
		this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMCancelValid(lmcsmq);
		// 9.2调用生产管理接口，更改业计划状态（主表、从表）、原料虚拟物料进程状态
		this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMCancel(lmcsmq);
		// 10、调用物流模块接口，执行原料卷出库撤销相关操作（接口由物流模块提供）；
		this.getBean(LmsApiServiceImpl.class).doCancelOut(cp);
		
		try{
			this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(vMaterialNo,false);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
		if ("1".equals(isOpen)) {
		
			// 记录成本异动点：20230811刘侣
			YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).doFind(vMaterialNo, null);
			ComBaseCbYdd cd = new ComBaseCbYdd();
			cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
			cd.setInstDisp("01");
			cd.setDataTypeIdx("O");
			// 当前产线：
			String currentMachine = ypd.getCoilno().contains("S") ? "YTSX" : ypd.getCoilno().contains("L") ? "YTZZ" : ypd.getCoilno().contains("P") ? "YTPZ" : ypd.getCoilno().contains("T") ? "YTTH" : ypd.getCoilno().contains("K") ? "YTHJ" : ypd.getCoilno().contains("F") ? "YTZJ" : "YT1";
			cd.setLocNo(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setInvQtyUnit("块");
			cd.setInvWidth(ypd.getWidth() != null ? String.valueOf(ypd.getWidth()) : "0");
			cd.setCreateId(userId);
			cd.setActivityId("41A");
			cd.setInvLength(ypd.getLength() != null ? String.valueOf(ypd.getLength()) : "0");
			cd.setManageip(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setProdName(ypd.getProd_name());
			cd.setInvThick(ypd.getThick() != null ? String.valueOf(ypd.getThick()) : "0");
			
			
			String prevcoil = ypd.getCoilno();
			// 上道产线：
			String prevMachine = prevcoil.contains("S") ? "YTSX" : prevcoil.contains("L") ? "YTZZ" : prevcoil.contains("P") ? "YTPZ" : prevcoil.contains("T") ? "YTTH" : prevcoil.contains("K") ? "YTHJ" : prevcoil.contains("F") ? "YTZJ" : "YT1";
			cd.setRefnoA("YT1".equals(prevMachine) ? ypd.getMaterailcoilno() : prevcoil); // 投料卷号
			cd.setSysId("IA");
			cd.setOrderItem(ypd.getOrderno());
			cd.setCrntMill(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setBeTransUnit("t");
			cd.setExecJobFunc("D");
			ComBaseSteel cbs = this.getMapper(ComBaseSteelMapper.class).findById(ypd.getSteelcode());
			if (cbs != null) {
				cd.setAlloyNo(cbs.getSteel_name()); // 牌号
			}
			
			cd.setAcctDate(new SimpleDateFormat("yyyyMMdd").format(now));
			cd.setLastMill(prevMachine); // 填上道工序产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setBeTransWgt(ypd.getFactweight() != null ? ypd.getFactweight() / 1000 : ypd.getFactweight());
			cd.setProdTypeNo("CTR");
			cd.setAppId("优特钢横剪取消上料");
			cd.setInvId("YT1".equals(currentMachine) ? ypd.getMaterailcoilno() : ypd.getCoilno());
			cd.setInvQty("1");

			// setSrcFac根据卷的物料属性去判断：20231031刘侣
			cd.setSrcFac("507101".equals(ypd.getObject_attr()) ? "1" : "3");
			
			cd.setGrade("40740801".equals(ypd.getJudgeresult()) ? "1" : "1"); // 正品　1　协议　3　次品　5
			cd.setProdClassNo("H");
			
			// 存入表：1、上料一抛：原料转库（47）（原料上料准备生产时抛送）
			cd.setActivityId("55A");
			cd.setExecJobFunc("D");
			cd.setDataTypeIdx("O");
			cd.setProdTypeNo("YT1".equals(prevMachine) && cd.getInvId().startsWith("L") ? "CCR" : "YT1".equals(prevMachine) ? "HCR" : "CTR");
			cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
			cd.setCrntMill(prevMachine); // 填上道产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setManageip(prevMachine); // 填上道产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
			cd.setLocNo(prevMachine); // 填上道产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
//			String currentMName = ypd.getCoilno().contains("S") ? "酸洗" : ypd.getCoilno().contains("L") ? "冷轧" : ypd.getCoilno().contains("P") ? "平整" : ypd.getCoilno().contains("T") ? "退火" : ypd.getCoilno().contains("K") ? "横剪" : ypd.getCoilno().contains("F") ? "分条" : "原料";
			String prevMName = prevcoil.contains("S") ? "酸洗" : prevcoil.contains("L") ? "冷轧" : prevcoil.contains("P") ? "平整" : prevcoil.contains("T") ? "退火" : prevcoil.contains("K") ? "开平" : prevcoil.contains("F") ? "分条" : "原料";
			cd.setAppId("优特" + prevMName + "取消转库");
			
			// 一次结算后第一次生产点上料的时候，不抛 转库和接收原料  改抛 12AB
			// 该卷是否刚刚一次结算完：可以根据提单里是否有这卷的一次结算数据进行判断：
//			int isYcJs = this.getMapper(YdmProductDetailMapper.class).isHasYcJs(ypd.getCoilno());
//			if (isYcJs <= 0) {
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypd.getMaterailcoilno());
//			}
			
			// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
			// 对已有数据进行修改：
			cd.setDataTypeIdx("N");
//			cd.setProdTypeNo("CTR");
			cd.setManageip("YTHJ");
			cd.setLocNo("YTHJ");
			cd.setAppId("开平取消接收原料");
			
			// 20231130刘侣
//			if (isYcJs > 0) {
//				cd.setActivityId("12AB");
//				cd.setAppId("取消来料加工");
//			}
			// end
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypd.getMaterailcoilno());
			// 三抛：酸洗上料（41，开始生产
			cd.setActivityId("41A");
			cd.setDataTypeIdx("O");
			cd.setAppId("开平取消上料");
			cd.setLastMill("YTHJ");
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypd.getMaterailcoilno());
			// end
		}
		
		
		r.setState("200");
		r.setMsgInfo("恢复计划成功");
		return r;
	}

	
	/**
	 * 动作处理 -恢复计划    deleteByProcessNo
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doUpdateWebmany(String vPlanNo, String vObjectNoVt,
			String vMaterialNo, String vMchCode, String vOprName)
					throws Exception {
		ResultModel r=new ResultModel();
		vOprName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprName==null){
			vOprName="";
		}
		
		String v_ret = "";
		Integer v_cnt;
		CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
		
		// 1)、验证横剪/开平作业计划主记录存在
		String ifplan = ifplan(vMchCode, vPlanNo);
		if (isEmpty(ifplan) != null) {
			throw new Exception(ifplan);
		}
		// 2）、验证横剪/开平作业计划明细记录存在
		String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(ifplanDetail) != null) {
			throw new Exception(ifplanDetail);
		}
		
		// 3 验证虚拟物料表中，原料卷计划信息存在
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(vObjectNoVt);
		int count = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if(count<=0){
			throw new Exception("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
		}
		
		// 4 验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
		if (isEmpty(isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo) )!= null) {
			throw new Exception(isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo));
		}
		MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
		cuttingM.setMachine_code(vMchCode);
		cuttingM.setSchedule_no(vPlanNo);
		cuttingM.setMaterial_no_vt(vObjectNoVt);
		cuttingM.setMaterial_no(vMaterialNo);
		List<MesCrCrossCuttingM> v_rec_ccm = this.getBean(
				MesCrCrossCuttingMMapper.class).findWithCondition(cuttingM,
						null, null, 0, 0);
		if (v_rec_ccm.get(0).getHand_over_status() != null
				&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
			throw new Exception("原料卷号：" + vMaterialNo + "当前已生产交工，不能恢复计划！"+"\n"
					+"可取消交工，并删除所有板垛记录后，再进行此操作！");
		}
		// 5.验证原料卷，当前未生成板垛实绩
		MesCrCrossCuttingD crcrD = new MesCrCrossCuttingD();
		crcrD.setProcess_no(v_rec_ccm.get(0).getProcess_no());
		v_cnt = this.getBean(MesCrCrossCuttingDMapper.class).count(crcrD);
		if (v_cnt > 0) {
			throw new Exception("原料卷号：" + vMaterialNo + "已生成板垛实绩，不能恢复计划"+"\n"
		+"可删除所有板垛记录后，再进行此操作！");
		}

		
		//6.调用生产管理接口，验证是否能执行相关操作，如果不满足条件，返回错误信息到前端
		this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMCancelValid(v_rec_ccm);

//		List<MesCrCrossCuttingM> lmcsm=new ArrayList<MesCrCrossCuttingM>();
//		lmcsm.add(cuttingM);
		//注意 ？？
		//this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMAddValid(v_rec_ccm);

		//7.调用物流模块接口，验证原料卷可撤销生产出库操作
		YdmProductDetail ypdu=new YdmProductDetail();
		ypdu.setCoilno(vMaterialNo);
		List<YdmProductDetail > listProductDetail=this.getMapper(YdmProductDetailMapper.class).findWithCondition(ypdu, null, null, 0, 0);
		cp.setObject(ypdu);
		r = this.getBean(LmsApiServiceImpl.class).doDepend(cp);
		if("500".equals(r.getState())){
			throw new Exception(r.getMsgInfo());
		}
		//8、删除横剪/开平实绩主记录
		this.getMapper(MesCrCrossCuttingMMapper.class).deleteByProcessNo(v_rec_ccm.get(0).getProcess_no());

		//9.调用生产管理接口，执行业计划状态、物料进程状态相关操作
		// 9.1调用生产管理接口，验证作业计划状态能执行此操作，否则，返回错误信息并提示
		List<MesCrCrossCuttingM> lmcsmq=new ArrayList<MesCrCrossCuttingM>();
		cuttingM.setInner_seq(Long.valueOf(v_rec_ccm.get(0).getInner_seq()));
		lmcsmq.add(cuttingM);
		this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMCancelValid(lmcsmq);
		// 9.2调用生产管理接口，更改业计划状态（主表、从表）、原料虚拟物料进程状态
		this.getBean(MesApiCrCrossCuttingMServiceImpl.class).MesCrCrossCuttingMCancel(lmcsmq);
		// 10、调用物流模块接口，执行原料卷出库撤销相关操作（接口由物流模块提供）；
		this.getBean(LmsApiServiceImpl.class).doCancelOut(cp);
		
		try{
			this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(vMaterialNo,false);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		r.setState("200");
		r.setMsgInfo("恢复计划成功");
		return r;
	}
	
	
	/**
	 * 保存  *  updateM
	 * */
	public ResultModel  doSaveWeb(MesCrCrossCuttingM m,
			String vPlanNo,String vObjectNoVt ,String vMaterialNo,String vMchCode,
			String vOprname,String vWrkDate,String vWrkOrd,String vWrkGrp) {
		ResultModel r=new ResultModel();
		
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprname==null){
			vOprname="";
		}
		String v_ret = "";
		Integer v_cnt;
		String v_machine_mark=null;
		String v_coil_no=null;
		if(vWrkDate==null){
			r.setMsgInfo("作业日期："+vWrkDate+"，不能为空！");
			r.setState("500");
			return r;
		}
		if(vWrkOrd==null || (!"1".equals(vWrkOrd) && !"2".equals(vWrkOrd))){
			r.setMsgInfo("班次代码："+vWrkOrd+"，无效，只能是 1（晚班）或2（早班）！请选择正确的班次！");
			r.setState("500");
			return r;
		}
		if(vWrkGrp==null || (!"1".equals(vWrkGrp) && !"2".equals(vWrkGrp) && !"3".equals(vWrkGrp) )){
			r.setMsgInfo("班组代码："+vWrkGrp+"无效，只能是 1（甲班）或2（乙班）或3（丙班）！请选择正确的班组！");
			r.setState("500");
			return r;
		}
		
		
		//1.验证横剪/开平作业计划主记录存在	
		if(isEmpty(ifplan(vMchCode, vPlanNo))!=null){
			r.setMsgInfo(ifplan(vMchCode, vPlanNo));
			r.setState("500");
			return r;
		}

		//2.验证横剪/开平作业计划明细记录存在
		String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(ifplanDetail)!=null) {
			r.setMsgInfo(ifplanDetail);
			r.setState("500");
			return r; 
		}
		//（3）、验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
		String notFinsh = isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(notFinsh)!= null) {
			r.setMsgInfo(notFinsh);
			r.setState("500");
			return r;
		}
		MesCrCrossCuttingM mm = new MesCrCrossCuttingM();
		mm.setMachine_code(vMchCode);
		mm.setSchedule_no(vPlanNo);
		mm.setMaterial_no_vt(vObjectNoVt);
		mm.setMaterial_no(vMaterialNo);
		List<MesCrCrossCuttingM> v_rec_ccm = this.getBean(
				MesCrCrossCuttingMMapper.class).findWithCondition(mm, null,
						null, 0, 0);
		if (v_rec_ccm.get(0).getHand_over_status() != null
				&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
			v_ret = ("原料卷号："+vMaterialNo+"\n当前已生产交工，不能修改生产实绩！\n可取消交工后，再进行此操作！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}

		//（4）、如果前端参数'{V_PARTIAL_REJECTED}' = '1'，表示部分原料卷吊销，则要按规格创建吊销的原料卷号信息
		//4.1
		if("1".equals(m.getPartial_rejected())){
			ComBaseMachine machine = new ComBaseMachine();
			machine.setMachine_code(vMchCode);
			v_cnt = this.getMapper(ComBaseMachineMapper.class).count(machine);
			if(v_cnt <= 0){
				v_ret = ("机台代码：" + vMchCode + "机台基础信息不存在！");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}

			//4.2获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
			//ComBaseMachine v_machine_mark1 = new ComBaseMachine();
			List<ComBaseMachine> listComBaseMachine= this.getMapper(ComBaseMachineMapper.class).findWithCondition(machine, null, null, 0, 0);
			v_machine_mark=listComBaseMachine.get(0).getMachine_mark();
			
			if (v_machine_mark == null) {
				v_ret = ("机台代码：" + vMchCode + "\n设备编号未配置，无法创建吊销卷号！");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			if(v_rec_ccm.get(0).getProcess_no()==null || "".equals(v_rec_ccm.get(0).getProcess_no())){
				r.setMsgInfo("横剪主实绩的生产处理号为空");
				r.setState("500");
				return r;
			}
			//4.3、1位流水（1 - 9）：从小到大的序号排查，不存在则占用mes_cr_cross_cutting_m
			for (int i =1 ; i <=9; i++) {
				v_coil_no=vMaterialNo.substring(1,8)+"K"+lpad(v_machine_mark, 2, "0")+"R"+i;
				//v_cnt =this.getMapper(MesCrCrossCuttingMMapper.class).findByvCoilNo(v_rec_ccm.get(i-1), v_coil_no);
				v_cnt =this.getMapper(MesCrCrossCuttingMMapper.class).findByvCoilNo(v_rec_ccm.get(0), v_coil_no);
				if(v_cnt==0){
					break;
				}
			}
			if(v_cnt>0){
				v_ret = "原料卷号："+vMaterialNo+"，部分吊销原料卷卷号生成失败，序号已全部占用！";																																							
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
		}
		//5）、修改横剪/开平实绩主记录   ？？
		//当feeding_wgt=999.03    feeding_wgt =to_number(#{param1.feeding_wgt}),可以
		if(m.getPartial_rejected()==null ){
			m.setPartial_rejected("");
		}
		this.getMapper(MesCrCrossCuttingMMapper.class).updateM(m, vOprname, v_coil_no,v_rec_ccm.get(0).getProcess_no(),vWrkDate,vWrkOrd,vWrkGrp);
		// （5）、新加功能：同步横剪/开平板垛实绩作业日期、班次、班组
		this.getMapper(MesCrCrossCuttingDMapper.class).updateD(v_rec_ccm.get(0).getProcess_no(),vWrkDate,vWrkOrd,vWrkGrp);
		
		//捆包数据的处理
		if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
			MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
			mcccm.setSchedule_no(v_rec_ccm.get(0).getSchedule_no());
			mcccm.setIs_bales(1);
			List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
			for(MesCrCrossCuttingM mmm:list_mcc){
				if(mmm.getMaterial_no().equals(v_rec_ccm.get(0).getMaterial_no())){
					continue;
				}
				MesCrCrossCuttingM m_main_plan = this.getMapper(MesCrCrossCuttingMMapper.class).findById(v_rec_ccm.get(0).getProcess_no());
				MesCrCrossCuttingM mccleo=new MesCrCrossCuttingM();
				mccleo.setProcess_no(mmm.getProcess_no());
				mccleo.setWrk_date(m_main_plan.getWrk_date());
				mccleo.setWrk_grp(m_main_plan.getWrk_grp());
				mccleo.setWrk_ord(m_main_plan.getWrk_ord());
				mccleo.setUpdate_opr(vOprname);
				mccleo.setUpdate_time(new Date());
				this.getMapper(MesCrCrossCuttingMMapper.class).update(mccleo);
				
			}
		}
		
		r.setState("200");
		r.setMsgInfo("保存成功");
		return r;
	}

	/**
	 * 按计划批量新增板朵按钮 doinsweb
	 * @param sum
	 * @return
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doAddsWeb(String vPlanNo, String vObjectNoVt,
			String vMaterialNo, String vMchCode, String vOprname) throws Exception {
		ResultModel r=new ResultModel();
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprname==null){
			vOprname="";
		}
		
		String v_ret = "";
		Integer v_cnt;
		String v_packing_no=null; // --板垛号
		
		// 1.验证横剪/开平作业计划主记录存在
		String ifplan = ifplan(vMchCode, vPlanNo);
		if (isEmpty(ifplan) != null ) {
			r.setMsgInfo(ifplan);
			r.setState("500");
			return r;
		}
		// 2验证横剪/开平作业计划明细记录存在
		String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(ifplanDetail)!= null) {
			r.setMsgInfo(ifplanDetail);
			r.setState("500");
			return r;
		}
		// （3）、验证虚拟物料表中，原料卷计划信息存在
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(vObjectNoVt);
		int count = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if (count<=0) {
			r.setMsgInfo("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
			r.setState("500");
			return r;
		}

		// 4.验证虚拟物料表中，板垛计划信息存在
		PlnMaterielDetail detail = new PlnMaterielDetail();
		detail.setObject_no_vt(vObjectNoVt);
		v_cnt = this.getBean(PlnMaterielDetailMapper.class).count(detail);
		if (v_cnt <= 0) {
			v_ret = ("虚拟卷号：" + vObjectNoVt + "板垛虚拟物料信息不存在！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}

		// 5验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
		String notFinsh = isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(notFinsh)!= null) {
			r.setMsgInfo(notFinsh);
			r.setState("500");
			return r;
		}
		MesCrCrossCuttingM m = new MesCrCrossCuttingM();
		m.setMachine_code(vMchCode);
		m.setSchedule_no(vPlanNo);
		m.setMaterial_no_vt(vObjectNoVt);
		m.setMaterial_no(vMaterialNo);
		List<MesCrCrossCuttingM> v_rec_ccm = this.getMapper(
				MesCrCrossCuttingMMapper.class).findWithCondition(m, null,
						null, 0, 0);
		if (v_rec_ccm.get(0).getHand_over_status() != null
				&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
			v_ret = ("原料卷号："+vMaterialNo+",当前已生产交工，不能批量新增板垛！\n可取消交工后，再进行此操作！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}

		// 6验证机台基础信息存在
		String ifbaseFinsh = ifbaseFinsh(vMchCode);
		if (isEmpty(ifbaseFinsh) != null) {
			r.setMsgInfo(ifbaseFinsh);
			r.setState("500");
			return r;
		}
		
		// 7.获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3com_base_machine.machine_mark）
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(vMchCode);
		List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class).find(machine, 0, 0);
		String v_machine_mark = lcbm.get(0).getMachine_mark();
		if (v_machine_mark == null) {
			v_ret = "机台代码：" + vMchCode + "设备编号未配置，无法创建板垛号！";
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		// 8。删除现有所有的板垛实绩 (mes_cr_cross_cutting_d )              ？？
		this.getMapper(MesCrCrossCuttingDMapper.class).deleteByProcessNo(v_rec_ccm.get(0).getProcess_no());
		
		//v_cnt = 1;// 临时记录板垛流水号
		// （9）、板垛编码规则：原料卷号（最初始原料卷号） + 1位工序代号（开平K）+ 2位设备代号（01-99） + 2位流水（01 - 99）
		v_packing_no = vMaterialNo.substring(0, 8) + "K"+ lpad(v_machine_mark, 2, "0");
		
		v_cnt = this.getMapper(MesCrCrossCuttingDMapper.class).doQuery("", v_packing_no);
		if(v_cnt==null){
			v_cnt=1;//第一垛
		}
		String v_packing_no_ext=null;//外部物料号
		// 9.循环板垛计划，逐一按计划创建板垛实绩
		PlnMaterielDetail tDetail = new PlnMaterielDetail();
		tDetail.setMat_object_no_vt(vObjectNoVt);
		// ？
		List<PlnMaterielDetail> cutlist = this.getMapper(
				PlnMaterielDetailMapper.class).findWithCondition(tDetail,
						"nvl(invalid_flg,0) = 0", "serial_no", 0, 0);
		if (cutlist != null && cutlist.size() > 0) {
			for (PlnMaterielDetail cut : cutlist) {
				if(v_cnt>99){
					r.setState("500");
					r.setMsgInfo("原料卷号："+vMaterialNo+"，新增板垛数量超出编码规则允许范围，流水号最大值99！");
					throw new Exception("原料卷号："+vMaterialNo+"，新增板垛数量超出编码规则允许范围，流水号最大值99！");
				}
				v_packing_no = vMaterialNo.substring(0, 8) + "K"
						+ lpad(v_machine_mark, 2, "0")+lpad(v_cnt+"", 2, "0");
				v_packing_no_ext=v_rec_ccm.get(0).getMaterial_no_src()+"-B"+lpad(v_cnt+"", 2, "0");
				
				this.getMapper(MesCrCrossCuttingDMapper.class)
						.doinsweb(cut, v_rec_ccm.get(0),vOprname,v_packing_no,v_packing_no_ext);
				v_cnt = v_cnt + 1;
			}
			//（10）、追加一条废副品物料信息
			//（10.1）、废副品编码规则：原料卷号（最初始原料卷号） + 1位工序代号（开平K）+ 2位设备代号（01-99） 
			v_packing_no=vMaterialNo.substring(0, 8) + "K"+ lpad(v_machine_mark, 2, "0");
			
			v_cnt = this.getMapper(MesCrCrossCuttingDMapper.class).doQuery2("", v_packing_no);
			if(v_cnt==null){
				v_cnt=0;
			}else if(v_cnt>9){
				r.setState("500");
				r.setMsgInfo("原料卷号："+vMaterialNo+"，废副品物料编号超出编码规则允许范围，流水号最大值9！");
				throw new Exception("原料卷号："+vMaterialNo+"，废副品物料编号超出编码规则允许范围，流水号最大值9！");
			}
			v_packing_no=vMaterialNo.substring(0, 8) + "K"+ lpad(v_machine_mark, 2, "0")+v_cnt+"B";
			
			// （10.2）、外部物料号（如新钢的包号）编码规则：原始卷号（新钢原料卷的卷号，来源于主表） + '-B' + '0B'
			v_packing_no_ext=v_rec_ccm.get(0).getMaterial_no_src()+"-B"+v_cnt+"B";
			//（10.3）、插入废副品实绩记录
			MesCrCrossCuttingD mcccd=new MesCrCrossCuttingD();
			mcccd.setPacking_no(v_packing_no);
			mcccd.setPacking_no_vt(null);
			mcccd.setPacking_no_ext(v_packing_no_ext);
			mcccd.setProcess_no(v_rec_ccm.get(0).getProcess_no());
			mcccd.setWrk_date(v_rec_ccm.get(0).getWrk_date());
			mcccd.setWrk_ord(v_rec_ccm.get(0).getWrk_ord());
			mcccd.setWrk_grp(v_rec_ccm.get(0).getWrk_grp());
			mcccd.setSteel_code(v_rec_ccm.get(0).getSteel_code());
			//2018-09-10
//			mcccd.setAim_thk(aim_thk);
//			mcccd.setAim_wdt(aim_wdt);
//			mcccd.setAim_len(aim_len);
//			mcccd.setAct_thk(act_thk);
//			mcccd.setAct_wdt(act_wdt);
//			mcccd.setAct_len(act_len);
//			mcccd.setPlate_cnt(plate_cnt);
//			mcccd.setPlate_single_wgt(plate_single_wgt);
			
			mcccd.setProduce_time(new Date());
			mcccd.setOrder_no(cutlist.get(0).getOrder_no());
			mcccd.setProd_order_no(cutlist.get(0).getProd_order_no());
			mcccd.setSurface_rst("40740601");
			mcccd.setCreate_opr(vOprname);
			mcccd.setCreate_time(new Date());
			
			// 2019-09-23 增加包装要求以便后续称重作业页面修改 panbin
			mcccd.setPk_ask_code(cutlist.get(0).getPk_ask_code());
			mcccd.setPk_ask_desc(cutlist.get(0).getPk_ask_desc());
			
			this.getMapper(MesCrCrossCuttingDMapper.class).insert(mcccd);
			
			// （10）、逐一循环板垛实绩（废副品物料除外），验证各板垛的 厚、宽、长、实重 都＞0
			double v_sum=0;//理重计算值
			List<MesCrCrossCuttingD> listD=	this.getMapper(MesCrCrossCuttingDMapper.class).FindMescrcrDByprocessNo(v_rec_ccm.get(0).getProcess_no());
			for (MesCrCrossCuttingD  cur_01 : listD) {
				if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
					v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板厚度必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
					v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板宽度必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
					v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板长度必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				if(cur_01.getPlate_cnt()==null || cur_01.getPlate_cnt()<=0){
					v_ret = "板垛号："+cur_01.getPacking_no()+"子板块数必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
//							if(cur_01.getPacking_net_wgt() ==null || cur_01.getPacking_net_wgt() <= 0){
//								v_ret = "板垛号:"+cur_01.getPacking_no()+"板垛重量必须大于0!"; 
//								r.setMsgInfo(v_ret);
//								r.setState("500");
//								return r;
//							}
				v_sum+=cur_01.getAct_wdt()*cur_01.getAct_len()*cur_01.getPlate_cnt();
			}
			
			//捆包数据的处理
			Double v_sum_total=0d;
			if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
				MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
				mcccm.setSchedule_no(v_rec_ccm.get(0).getSchedule_no());
				mcccm.setIs_bales(1);
				List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
				
				for(MesCrCrossCuttingM mmm:list_mcc){
					v_sum_total+=mmm.getMtr_thr_wgt();
				}
				v_rec_ccm.get(0).setMtr_thr_wgt(v_sum_total);
			}
			
			// （10'）、逐一循环板垛实绩（废副品物料除外），重新计算各板垛理重值：= 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
		   List<MesCrCrossCuttingD> lmccd = this.getMapper(MesCrCrossCuttingDMapper.class).doQueryMes(v_rec_ccm.get(0).getProcess_no(),"");
		   int i=1;
		   double lastWgt=0;
		   for(MesCrCrossCuttingD d:lmccd){
			   // （10.1'）、前N-1个板垛理重 = 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
			   //this.getMapper(MesCrCrossCuttingDMapper.class).updateMdd(v_sum,d.getPacking_no());
				//四舍五入
			   BigDecimal b=null;
			   double f1=0;
			   if(Integer.parseInt(d.getXh())<Integer.parseInt(d.getCnt())){
				   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()*d.getAct_wdt()*d.getAct_len()*d.getPlate_cnt()/v_sum);  
				   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
				   lastWgt+=f1;
			   }else if(Integer.parseInt(d.getXh())==Integer.parseInt(d.getCnt())){
				   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()-lastWgt);  
				   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
			   }
				MesCrCrossCuttingD mccccd=new MesCrCrossCuttingD();
				mccccd.setPacking_no(d.getPacking_no());
				mccccd.setPacking_thr_wgt(f1);
				this.getMapper(MesCrCrossCuttingDMapper.class).update(mccccd);
				i++;
		   }
			
		}
		
		r.setState("200");
		r.setMsgInfo("按计划批量新增板垛成功");
		
		return r;
	}

	
	/**
	 * 新增板垛按钮 pln_cuttolength_plan  doinsweb2
	 * @param vPlanNo
	 * @param vObjectNoVt
	 * @param vMaterialNo
	 * @param vSerialNo
	 * @param vMchCode
	 * @param vOprname
	 * @return
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doAddmaterielWeb(String vPlanNo, String vObjectNoVt,
			String vMaterialNo, Integer vSerialNo, String vMchCode, String vOprname) throws Exception{
		ResultModel r=new ResultModel();
		
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprname==null){
			vOprname="";
		}
		
		String v_ret = "";
		Integer v_cnt;
		MesCrCrossCuttingM v_rec_ccm;
		PlnMaterielDetail v_rec_pmd;
		String v_packing_no = null;
		
		// 1)、验证横剪/开平作业计划主记录存在
		String ifplan = ifplan(vMchCode, vPlanNo);
		if (isEmpty(ifplan) != null) {
			r.setMsgInfo(ifplan);
			r.setState("500");
			return r;
		}
		// （2）、验证横剪/开平作业计划明细记录存在
		String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(ifplanDetail) != null) {
			r.setMsgInfo(ifplanDetail);
			r.setState("500");
			return r;
		}
		
		// 3 验证虚拟物料表中，原料卷计划信息存在 pln_materiel_detail
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(vObjectNoVt);
		int count = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if(count<=0){
			r.setMsgInfo("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
			r.setState("500");
			return r;
		}
		// （4）验证虚拟物料表中，板垛计划信息存在 pln_materiel_detail
		PlnMaterielDetail mater2 = new PlnMaterielDetail();
		mater2.setSerial_no(vSerialNo);
		v_cnt = this.getMapper(PlnMaterielDetailMapper.class).count(mater2);
		if (v_cnt <= 0) {
			v_ret = "序列号：" + vSerialNo + "，板垛虚拟物料信息不存在！";
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		// pln_materiel_detail
		v_rec_pmd = this.getMapper(PlnMaterielDetailMapper.class).findById(
				vSerialNo);
		if (!v_rec_pmd.getMat_object_no_vt().equals(vObjectNoVt)) {
			v_ret = ("序列号：" + vSerialNo + "板垛虚拟原料卷号不匹配！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}

		// （5）、验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态 mes_cr_cross_cutting_m
		MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
		cuttingM.setMachine_code(vMchCode);
		cuttingM.setSchedule_no(vPlanNo);
		cuttingM.setMaterial_no_vt(vObjectNoVt);
		cuttingM.setMaterial_no(vMaterialNo);
		// into 给新的字段赋值
		v_cnt = this.getBean(MesCrCrossCuttingMMapper.class)
				.count(cuttingM);
		if(v_cnt <= 0){
			v_ret = ("原料卷号：" + vMaterialNo + "当前不存在开平作业主实绩，请确认是否已操作上料！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		MesCrCrossCuttingM mCross = new MesCrCrossCuttingM();
		mCross.setMachine_code(vMchCode);
		mCross.setSchedule_no(vPlanNo);
		mCross.setMaterial_no_vt(vObjectNoVt);
		mCross.setMaterial_no(vMaterialNo);
		v_rec_ccm =  this.getBean(
				MesCrCrossCuttingMMapper.class).find(mCross, 0, 0).get(0);
		if(v_rec_ccm.getHand_over_status() != null
				&& !v_rec_ccm.getHand_over_status().equals("0")) {
			v_ret = ("原料卷号：" + vMaterialNo + "当前已生产交工，不能新增板垛！\n可取消交工后，再进行此操作！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		// （6）、验证机台基础信息存在
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(vMchCode);
		v_cnt = this.getMapper(ComBaseMachineMapper.class).count(machine);
		if (v_cnt <= 0) {
			v_ret = "机台代码：" + vMchCode + "，机台基础信息不存在！";
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		// 7.获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
		List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class).find(machine, 0, 0);
		String v_machine_mark = lcbm.get(0).getMachine_mark();
		if (v_machine_mark == null) {
			v_ret = "机台代码：" + vMchCode + "，设备编号未配置，无法创建板垛号！";
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}

		// 8 生成板垛编号
		v_packing_no = vMaterialNo.substring(0, 8) + "K"
				+ lpad(v_machine_mark, 2, "0");
		v_cnt = this.getBean(MesCrCrossCuttingDMapper.class).doQuery(v_rec_ccm.getProcess_no(),v_packing_no);
		if (v_cnt == null) {
			v_cnt = 1;
		}
		else if(v_cnt>99){
			r.setState("500");
			r.setMsgInfo("原料卷号："+vMaterialNo+"，新增板垛编号超出编码规则允许范围，流水号最大值99！");
			return r;
		}
		v_packing_no = v_packing_no+lpad((v_cnt).toString(), 2, "0");
		// （8.2）、外部物料号（如新钢的包号）编码规则：原始卷号（新钢原料卷的卷号，来源于主表） + '-B' + 2位流水（01 - 99）
		String v_packing_no_ext=v_rec_ccm.getMaterial_no_src()+"-B"+lpad((v_cnt).toString(), 2, "0");
		
		// （9）、插入板垛实绩记录
		this.getBean(MesCrCrossCuttingDMapper.class).doinsweb2(v_packing_no,
				v_rec_ccm, v_rec_pmd, vOprname,v_packing_no_ext);
		
		// （10）、逐一循环板垛实绩（废副品物料除外），验证各板垛的 厚、宽、长、实重 都＞0
		double v_sum=0;//理重计算值
		List<MesCrCrossCuttingD> listD=	this.getMapper(MesCrCrossCuttingDMapper.class).FindMescrcrDByprocessNo(v_rec_ccm.getProcess_no());
		for (MesCrCrossCuttingD  cur_01 : listD) {
			if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
				v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板厚度必须大于0！"; 
				throw new Exception(v_ret);
			}
			if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
				v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板宽度必须大于0！"; 
				throw new Exception(v_ret);
			}
			if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
				v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板长度必须大于0！"; 
				throw new Exception(v_ret);
			}
			if(cur_01.getPlate_cnt()==null || cur_01.getPlate_cnt()<=0){
				v_ret = "板垛号："+cur_01.getPacking_no()+"子板块数必须大于0！"; 
				throw new Exception(v_ret);
			}
			v_sum+=cur_01.getAct_wdt()*cur_01.getAct_len()*cur_01.getPlate_cnt();
		}
		
		//捆包数据的处理
		Double v_sum_total=0d;
		if(v_rec_ccm.getIs_main_plan()!=null && v_rec_ccm.getIs_main_plan().intValue()==1){
			MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
			mcccm.setSchedule_no(v_rec_ccm.getSchedule_no());
			mcccm.setIs_bales(1);
			List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
			
			for(MesCrCrossCuttingM mmm:list_mcc){
				v_sum_total+=mmm.getMtr_thr_wgt();
			}
			v_rec_ccm.setMtr_thr_wgt(v_sum_total);
		}
		
		// （10'）、逐一循环板垛实绩（废副品物料除外），重新计算各板垛理重值：= 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
	   List<MesCrCrossCuttingD> lmccd = this.getMapper(MesCrCrossCuttingDMapper.class).doQueryMes(v_rec_ccm.getProcess_no(),"");
	   int i=1;
	   double lastWgt=0;
	   for(MesCrCrossCuttingD d:lmccd){
		   // （10.1'）、前N-1个板垛理重 = 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
		   //this.getMapper(MesCrCrossCuttingDMapper.class).updateMdd(v_sum,d.getPacking_no());
			//四舍五入
		   BigDecimal b=null;
		   double f1=0;
		   if(Integer.parseInt(d.getXh())<Integer.parseInt(d.getCnt())){
			   b= new BigDecimal(v_rec_ccm.getMtr_thr_wgt()*d.getAct_wdt()*d.getAct_len()*d.getPlate_cnt()/v_sum);  
			   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
			   lastWgt+=f1;
		   }else if(Integer.parseInt(d.getXh())==Integer.parseInt(d.getCnt())){
			   b= new BigDecimal(v_rec_ccm.getMtr_thr_wgt()-lastWgt);  
			   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
		   }
			MesCrCrossCuttingD mccccd=new MesCrCrossCuttingD();
			mccccd.setPacking_no(d.getPacking_no());
			mccccd.setPacking_thr_wgt(f1);
			mccccd.setPk_ask_code(v_rec_pmd.getPk_ask_code());
			mccccd.setPk_ask_desc(v_rec_pmd.getPk_ask_desc());
			this.getMapper(MesCrCrossCuttingDMapper.class).update(mccccd);
			i++;
	   }
		
		r.setState("200");
		r.setMsgInfo("新增板垛成功!");
		
		return r;
	}

	/***
	 * 动作处理--修改板垛按钮  updateMescrcrossD  
	 * AIM_WDT  AIM_LEN  PACKING_TTL_WGT
	 * Packing_no()
	 *PACKING_BOX_WGT  PACKING_THR_WGT  	
       PLATE_CNT
	 * 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel updateStack(MesCrCrossCuttingD d , String vPlanNo,String vObjectNoVt ,
			String vMaterialNo,String vMchCode,String vOprname) throws Exception{
		ResultModel r=new ResultModel();
		
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprname==null){
			vOprname="";
		}
		String v_ret = "";
		Integer v_cnt;
		MesCrCrossCuttingD v_rec_ccd;
		String vPackingNo=d.getPacking_no();
	
		// 1验证横剪/开平作业计划主记录存在
		String ifplan = ifplan(vMchCode, vPlanNo);
		if (isEmpty(ifplan) != null) {
			r.setMsgInfo(ifplan);
			r.setState("500");
			return r;
		}

		// 2.验证横剪/开平作业计划明细记录存在
		String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(ifplanDetail) != null) {
			r.setMsgInfo(ifplanDetail);
			r.setState("500");
			return r;
		}

		// 3.验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
		String notFinsh = isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
		if (isEmpty(notFinsh)!= null) {
			r.setMsgInfo(notFinsh);
			r.setState("500");
			return r;
		}
		MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
		cuttingM.setMachine_code(vMchCode);
		cuttingM.setSchedule_no(vPlanNo);
		cuttingM.setMaterial_no_vt(vObjectNoVt);
		cuttingM.setMaterial_no(vMaterialNo);
		List<MesCrCrossCuttingM> v_rec_ccm = this.getBean(
				MesCrCrossCuttingMMapper.class).findWithCondition(cuttingM,
						null, null, 0, 0);
		if (v_rec_ccm.get(0).getHand_over_status() != null
				&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
			v_ret = ("原料卷号："+vMaterialNo+"当前已生产交工，不能修改板垛信息！\n可取消交工后，再进行此操作！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		// 4 验证选中的板垛实绩记录存在
		MesCrCrossCuttingD mcccd=new MesCrCrossCuttingD();
		mcccd.setPacking_no(vPackingNo);
		v_cnt =this.getMapper(MesCrCrossCuttingDMapper.class).count(mcccd);
		if (v_cnt <= 0) {
			v_ret = ("板垛号：" + vPackingNo + "，板垛实绩记录不存在！");
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		
		v_rec_ccd = this.getMapper(MesCrCrossCuttingDMapper.class).findById(vPackingNo);
		if (!v_rec_ccd.getProcess_no().equals(v_rec_ccm.get(0).getProcess_no())) {
			v_ret = "板垛号：" + vPackingNo + "，生产处理号与开平作业主实绩不匹配！";
			r.setMsgInfo(v_ret);
			r.setState("500");
			return r;
		}
		//5、修改板垛实绩记录
		this.getMapper(MesCrCrossCuttingDMapper.class).updateMescrcrossD(d, vOprname, vPackingNo);
		
		// （10）、逐一循环板垛实绩（废副品物料除外），验证各板垛的 厚、宽、长、实重 都＞0
		double v_sum=0;//理重计算值
		List<MesCrCrossCuttingD> listD=	this.getMapper(MesCrCrossCuttingDMapper.class).FindMescrcrDByprocessNo(v_rec_ccm.get(0).getProcess_no());
		for (MesCrCrossCuttingD  cur_01 : listD) {
			if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
				v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板厚度必须大于0！"; 
				throw new Exception(v_ret);
			}
			if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
				v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板宽度必须大于0！"; 
				throw new Exception(v_ret);
			}
			if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
				v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板长度必须大于0！"; 
				throw new Exception(v_ret);
			}
			if(cur_01.getPlate_cnt()==null || cur_01.getPlate_cnt()<=0){
				v_ret = "板垛号："+cur_01.getPacking_no()+"子板块数必须大于0！"; 
				throw new Exception(v_ret);
			}
			v_sum+=cur_01.getAct_wdt()*cur_01.getAct_len()*cur_01.getPlate_cnt();
		}
		
		//捆包数据的处理
		Double v_sum_total=0d;
		if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
			MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
			mcccm.setSchedule_no(v_rec_ccm.get(0).getSchedule_no());
			mcccm.setIs_bales(1);
			List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
			
			for(MesCrCrossCuttingM mmm:list_mcc){
				v_sum_total+=mmm.getMtr_thr_wgt();
			}
			v_rec_ccm.get(0).setMtr_thr_wgt(v_sum_total);
		}
		
		// （10'）、逐一循环板垛实绩（废副品物料除外），重新计算各板垛理重值：= 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
	   List<MesCrCrossCuttingD> lmccd = this.getMapper(MesCrCrossCuttingDMapper.class).doQueryMes(v_rec_ccm.get(0).getProcess_no(),"");
	   int i=1;
	   double lastWgt=0;
	   for(MesCrCrossCuttingD ddd:lmccd){
		   // （10.1'）、前N-1个板垛理重 = 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
		   //this.getMapper(MesCrCrossCuttingDMapper.class).updateMdd(v_sum,d.getPacking_no());
			//四舍五入
		   BigDecimal b=null;
		   double f1=0;
		   if(Integer.parseInt(ddd.getXh())<Integer.parseInt(ddd.getCnt())){
			   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()*ddd.getAct_wdt()*ddd.getAct_len()*ddd.getPlate_cnt()/v_sum);  
			   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
			   lastWgt+=f1;
		   }else if(Integer.parseInt(ddd.getXh())==Integer.parseInt(ddd.getCnt())){
			   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()-lastWgt);  
			   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
		   }
			MesCrCrossCuttingD mccccd=new MesCrCrossCuttingD();
			mccccd.setPacking_no(ddd.getPacking_no());
			mccccd.setPacking_thr_wgt(f1);
			this.getMapper(MesCrCrossCuttingDMapper.class).update(mccccd);
			i++;
	   }
		
		r.setState("200");
		r.setMsgInfo("修改板垛成功");
		
		return r;
	}


	/***
	 * 动作处理--删除板垛按钮  
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel deletesTack(String vPlanNo,String vObjectNoVt ,	String vMaterialNo ,
			 String vPackingNo,String vMchCode,String vOprname) throws Exception{
		ResultModel r=new ResultModel();
		
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprname==null){
			vOprname="";
		}
		String v_ret=null;
		Integer v_cnt;
		List<MesCrCrossCuttingM> v_rec_ccm;
		try {
				// 1.验证横剪/开平作业计划主记录存在
			    String ifplan = ifplan(vMchCode, vPlanNo);
				if (isEmpty(ifplan) != null) {
					r.setMsgInfo(ifplan);
					r.setState("500");
					return r;
				}
				// 2.验证横剪/开平作业计划明细记录存在
				String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
				if (isEmpty(ifplanDetail) != null) {
					r.setMsgInfo(ifplanDetail);
					r.setState("500");
					return r;
				}
				// 3 .验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
				String notFinsh = isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
				if (isEmpty(notFinsh)!= null) {
					r.setMsgInfo(notFinsh);
					r.setState("500");
					return r;
				}
				MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
				cuttingM.setMachine_code(vMchCode);
				cuttingM.setSchedule_no(vPlanNo);
				cuttingM.setMaterial_no_vt(vObjectNoVt);
				cuttingM.setMaterial_no(vMaterialNo);
				v_rec_ccm = this.getMapper(MesCrCrossCuttingMMapper.class)
						.findWithCondition(cuttingM, null, null, 0, 0);
				if (v_rec_ccm.get(0).getHand_over_status() != null
						&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
					v_ret = "原料卷号：" + vMaterialNo + "，当前已生产交工，不能删除板垛！"+"\n可取消交工后，再进行此操作！";
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}

				// 4.、验证选中的板垛实绩记录存在mes_cr_cross_cutting_d
				MesCrCrossCuttingD md=new MesCrCrossCuttingD();
				md.setPacking_no(vPackingNo);
				v_cnt=this.getMapper(MesCrCrossCuttingDMapper.class).count(md);
				if(v_cnt<=0){
					v_ret = ("板垛号：" + vPackingNo + " 板垛实绩记录不存在！");
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				//MesCrCrossCuttingD v_rec_ccd=	this.getMapper(MesCrCrossCuttingDMapper.class).findAllByPackingNo(vPackingNo);
				MesCrCrossCuttingD v_rec_ccd=	this.getMapper(MesCrCrossCuttingDMapper.class).findById(vPackingNo);
				if (!v_rec_ccd.getProcess_no().equals(v_rec_ccm.get(0).getProcess_no())) {
					v_ret = "板垛号：" + vPackingNo + "，生产处理号与开平作业主实绩不匹配！";
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				//（5）、废副品物料信息不允许删除，通过板垛号最后一位等于大写字母B来判断
				if("B".equals(vPackingNo.substring(vPackingNo.length()-1))){
					r.setMsgInfo("废副品物料信息不允许删除！");
					r.setState("500");
					return r;
				}
				//（6）、修改板垛实绩记录
				this.getMapper(MesCrCrossCuttingDMapper.class).delete(vPackingNo);
				
				// （10）、逐一循环板垛实绩（废副品物料除外），验证各板垛的 厚、宽、长、实重 都＞0
				double v_sum=0;//理重计算值
				List<MesCrCrossCuttingD> listD=	this.getMapper(MesCrCrossCuttingDMapper.class).FindMescrcrDByprocessNo(v_rec_ccm.get(0).getProcess_no());
				for (MesCrCrossCuttingD  cur_01 : listD) {
					if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
						v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板厚度必须大于0！"; 
						throw new Exception(v_ret);
					}
					if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
						v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板宽度必须大于0！"; 
						throw new Exception(v_ret);
					}
					if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
						v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板长度必须大于0！"; 
						throw new Exception(v_ret);
					}
					if(cur_01.getPlate_cnt()==null || cur_01.getPlate_cnt()<=0){
						v_ret = "板垛号："+cur_01.getPacking_no()+"子板块数必须大于0！"; 
						throw new Exception(v_ret);
					}
					v_sum+=cur_01.getAct_wdt()*cur_01.getAct_len()*cur_01.getPlate_cnt();
				}
				
				//捆包数据的处理
				Double v_sum_total=0d;
				if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
					MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
					mcccm.setSchedule_no(v_rec_ccm.get(0).getSchedule_no());
					mcccm.setIs_bales(1);
					List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
					
					for(MesCrCrossCuttingM mmm:list_mcc){
						v_sum_total+=mmm.getMtr_thr_wgt();
					}
					v_rec_ccm.get(0).setMtr_thr_wgt(v_sum_total);
				}
				
				// （10'）、逐一循环板垛实绩（废副品物料除外），重新计算各板垛理重值：= 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
			   List<MesCrCrossCuttingD> lmccd = this.getMapper(MesCrCrossCuttingDMapper.class).doQueryMes(v_rec_ccm.get(0).getProcess_no(),"");
			   int i=1;
			   double lastWgt=0;
			   for(MesCrCrossCuttingD ddd:lmccd){
				   // （10.1'）、前N-1个板垛理重 = 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
				   //this.getMapper(MesCrCrossCuttingDMapper.class).updateMdd(v_sum,d.getPacking_no());
					//四舍五入
				   BigDecimal b=null;
				   double f1=0;
				   if(Integer.parseInt(ddd.getXh())<Integer.parseInt(ddd.getCnt())){
					   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()*ddd.getAct_wdt()*ddd.getAct_len()*ddd.getPlate_cnt()/v_sum);  
					   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
					   lastWgt+=f1;
				   }else if(Integer.parseInt(ddd.getXh())==Integer.parseInt(ddd.getCnt())){
					   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()-lastWgt);  
					   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
				   }
					MesCrCrossCuttingD mccccd=new MesCrCrossCuttingD();
					mccccd.setPacking_no(ddd.getPacking_no());
					mccccd.setPacking_thr_wgt(f1);
					this.getMapper(MesCrCrossCuttingDMapper.class).update(mccccd);
					i++;
			   }
				
			r.setState("200");
			r.setMsgInfo("删除板垛按钮成功");
		} catch (Exception e) {
			r.setState("500");
			r.setMsgInfo("删除板垛按钮失败");
			r.setErrorInfo(e.getMessage());
			throw new Exception(e.getMessage());
		}
		return  r;
	}

	/**
	 * 动作处理--删除所有板垛按钮 deleteByProcessNo
	 */
	public ResultModel deleteAllstack(String vPlanNo, String vObjectNoVt,
			String vMaterialNo, String vMchCode, String vOprName) {
		ResultModel r =new ResultModel();
		vOprName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprName==null){
			vOprName="";
		}
		String v_ret = ""; // 返回到前端的错误提示信息
		Integer v_cnt;
		List<MesCrCrossCuttingM> v_rec_ccm;
		try {
			// 1.验证横剪/开平作业计划主记录存在
			String ifplan = ifplan(vMchCode, vPlanNo);
			if (isEmpty(ifplan) != null) {
				r.setMsgInfo(ifplan);
				r.setState("500");
				return r;
			}
			// 2.验证横剪/开平作业计划明细记录存在
			String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
			if (isEmpty(ifplanDetail) != null) {
				r.setMsgInfo(ifplanDetail);
				r.setState("500");
				return r;
			}
			// 3.验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
			String notFinsh = isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
			if (isEmpty(notFinsh)!= null) {
				r.setMsgInfo(notFinsh);
				r.setState("500");
				return r;
			}
			MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
			cuttingM.setMachine_code(vMchCode);
			cuttingM.setSchedule_no(vPlanNo);
			cuttingM.setMaterial_no_vt(vObjectNoVt);
			cuttingM.setMaterial_no(vMaterialNo);
			v_rec_ccm = this.getMapper(MesCrCrossCuttingMMapper.class)
					.findWithCondition(cuttingM, null, null, 0, 0);
			if (v_rec_ccm.get(0).getHand_over_status() != null
					&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
				v_ret = ("原料卷号：" + vMaterialNo + "当前已生产交工，不能删除板垛！\n可取消交工后，再进行此操作！");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}

			// 4、验证选中的板垛实绩记录存在mes_cr_cross_cutting_d
			MesCrCrossCuttingD mcccd=new MesCrCrossCuttingD();
			mcccd.setProcess_no(v_rec_ccm.get(0).getProcess_no());
			int count = this.getMapper(MesCrCrossCuttingDMapper.class).count(mcccd);
			if (count <= 0) {
				v_ret = ("原料卷号：" + vMaterialNo + " 当前无板垛实绩!");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			// （5）、删除板垛实绩记录
			this.getBean(MesCrCrossCuttingDMapper.class).deleteByProcessNo(
					v_rec_ccm.get(0).getProcess_no());
			r.setState("200");
			r.setMsgInfo("删除所有板垛成功!");
		} catch (Exception e) {
			e.printStackTrace();
			r.setState("500");
			r.setMsgInfo("删除所有板垛失败!");
		}
		return r;
	}


	/***
	 * 动作处理--称重保存按钮
	 * 
	 * CL_PLAN_NO--V_PLAN_NO OBJECT_NO_VT-- V_OBJECT_NO_VT OBJECT_NO --doinsert
	 * V_MATERIAL_NO
	 * 
	 * mes_cr_cross_cutting_wgt.serial_no mes_cr_cross_cutting_m
	 * mes_cr_cross_cutting_d
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel insertWeigh(String vPlanNo,String vObjectNoVt ,
			String vMaterialNo, String vPackingNo,
			String vWgtSource, String vWgtValue, String vWgtSort,
			String vMchCode,String vOprname,String pk_ask_code , String pk_ask_desc) throws Exception {
		ResultModel r=new ResultModel();
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprname==null){
			vOprname="";
		}
		String v_ret = "";
		Integer v_cnt;
		MesCrCrossCuttingWgt wgt;
		try {
			// 1验证横剪/开平作业计划主记录存在
			String ifplan = ifplan(vMchCode, vPlanNo);
			if (isEmpty(ifplan) != null) {
				r.setMsgInfo(ifplan);
				r.setState("500");
				return r;
			}

			// 2.验证横剪/开平作业计划明细记录存在
			String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
			if (isEmpty(ifplanDetail)!= null) {
				r.setMsgInfo(ifplanDetail);
				r.setState("500");
				return r;
			}

			// 3.验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
			String notFinsh = isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
			if (isEmpty(notFinsh)!= null) {
				r.setMsgInfo(notFinsh);
				r.setState("500");
				return r;
			}
			MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
			cuttingM.setMachine_code(vMchCode);
			cuttingM.setSchedule_no(vPlanNo);
			cuttingM.setMaterial_no_vt(vObjectNoVt);
			cuttingM.setMaterial_no(vMaterialNo);
			List<MesCrCrossCuttingM> v_rec_ccm = this.getBean(
					MesCrCrossCuttingMMapper.class).findWithCondition(cuttingM,
							null, null, 0, 0);
			if (v_rec_ccm.get(0).getHand_over_status() != null
					&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
				v_ret = "原料卷号："+vMaterialNo+"当前已生产交工，不能修改板垛重量！\n可取消交工后，再进行此操作！";
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			// 4 验证选中的板垛实绩记录存在
			MesCrCrossCuttingD mcccd=new MesCrCrossCuttingD();
			mcccd.setPacking_no(vPackingNo);
			v_cnt =this.getMapper(MesCrCrossCuttingDMapper.class).count(mcccd);
			if (v_cnt <= 0) {
				v_ret = ("板垛号：" + vPackingNo + "，板垛实绩记录不存在！");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			MesCrCrossCuttingD v_rec_ccd = this.getMapper(
					MesCrCrossCuttingDMapper.class).findById(
							vPackingNo);
			if (!v_rec_ccd.getProcess_no().equals(v_rec_ccm.get(0).getProcess_no())) {
				v_ret = "板垛号：" + vPackingNo + "，生产处理号与开平作业主实绩不匹配！";
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			// 5. 验证重量来源参数有效：重量来源（1：采集、2：人工）
			if (vWgtSource == null
					|| (!vWgtSource.equals("1") && !vWgtSource.equals("2"))) {
				v_ret = "重量来源代码：" + vWgtSource + "，参数值无效（1：采集、2：人工）！";
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			// 6验证重量类别参数有效：重量类别（1：毛重、2：皮重、3：净重）
			if (vWgtSort == null
					|| (!vWgtSort.equals("1") && !vWgtSource.equals("2") && !vWgtSource
							.equals("3"))) {
				v_ret = "重量类别代码：" + vWgtSort + "，参数值无效（1：毛重、2：皮重、3：净重）！";
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			// 7.创建一条称重保存的历史记录
			// 7.1称重编号：YYMMDD + 5位流水
			// 7.2 新增称重历史记录
			SimpleDateFormat formatYmd = new SimpleDateFormat("yyMMdd");
			String v_serial_no = formatYmd.format(new Date());
			v_cnt = this.getMapper(MesCrCrossCuttingWgtMapper.class).findByvSerialNo(v_serial_no);
			if (v_cnt == null) {
				v_cnt = 1;// 第一垛
			}
			v_serial_no = v_serial_no+ lpad(v_cnt.toString(), 5, "0");

			// 新增称重历史记录--MesCrCrossCuttingWgtMapper
			this.getMapper(MesCrCrossCuttingWgtMapper.class).doinsert(
					v_serial_no, v_rec_ccd, vWgtSource, vWgtSort, vWgtValue,vOprname);

			// 8.0 修改板垛相关重量
			// MesCrCrossCuttingDMapper
			this.getMapper(MesCrCrossCuttingDMapper.class).updateCuttingD(
					vWgtSort, vWgtValue, vOprname, vPackingNo, v_serial_no);
			
			// 修改包装要求
			MesCrCrossCuttingD mesD = new MesCrCrossCuttingD();
			mesD.setPacking_no(vPackingNo);
			mesD.setPk_ask_code(pk_ask_code);
			mesD.setPk_ask_desc(pk_ask_desc);
			this.getMapper(MesCrCrossCuttingDMapper.class).update(mesD);
			
			r.setState("200");
			r.setMsgInfo("称重保存成功");
		} catch (Exception e) {
			r.setState("500");
			r.setMsgInfo("称重保存失败");
			e.printStackTrace();
			throw new Exception("称重保存失败");
		}
		return r;
	}

	/***
	 * 动作处理--打印标签按钮
	 * 
	 * MES_CR_CROSS_CUTTING_D 横剪成品实绩  findAllByLabel
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel printLabel(List<MesCrCrossCuttingD> listLabel,String v_source) throws Exception {
		ResultModel r = new ResultModel();
		Integer v_cnt;
		// 1.逐一验证传入的板垛号，对应的板垛实绩存在
		try {
			if (listLabel.size() != 0) {
				for (MesCrCrossCuttingD s1 : listLabel) {
					MesCrCrossCuttingD s2=new MesCrCrossCuttingD();
					s2.setPacking_no(s1.getPacking_no());
					v_cnt = this.getMapper(MesCrCrossCuttingDMapper.class).count(s2);
					if (v_cnt <= 0) {
						r.setMsgInfo("板垛号：" + s1.getPacking_no() + "板垛记录不存在！");
						r.setState("500");
						return r;
					}
					MesCrCrossCuttingD mcccd = this.getMapper(MesCrCrossCuttingDMapper.class).findById(s1.getPacking_no());
					if(mcccd.getPlate_cnt()==null || mcccd.getPlate_cnt()<=0){
						r.setMsgInfo("板垛号："+ s1.getPacking_no() + "，子板块数未指定，不能打印！");
						r.setState("500");
						return r;
					}
					if(mcccd.getPacking_net_wgt()==null || mcccd.getPacking_net_wgt()<=0){
						r.setMsgInfo("板垛号："+s1.getPacking_no()+"，还未过磅，不能打印！");
						r.setState("500");
						return r;
					}
				}
				List<String> strList = new ArrayList<String>();
				for (MesCrCrossCuttingD s4 : listLabel) {
					strList.add(s4.getPacking_no());
				}
				HashMap<String,Object> param = new HashMap<String,Object>();
				param.put("list", strList);
				List<MesCrCrossCuttingD> list=new ArrayList<>();
				if(v_source.equals("1")){//生成板垛的标签信息，如果 V_SOURCE = '1'（即使用新钢冷轧的模板）
					list=this.getMapper(MesCrCrossCuttingDMapper.class).doQueryPrint(strList,"");
				}else if(v_source.equals("0")){// 使用优特钢内部标牌
					list=this.getMapper(MesCrCrossCuttingDMapper.class).doQueryPrint1(strList,"");
				}
//				保存打印记录
				for(MesCrCrossCuttingD d:list){
					MesTpmPrintLog log=new MesTpmPrintLog();
					BeanUtils.copyProperties(d, log);
					log.setId(UUID.randomUUID().toString());
					String userName=(String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
					log.setPrintname(userName);
					SimpleDateFormat dfm=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					log.setPrinttime(dfm.format(new Date()));
					this.getMapper(MesTpmPrintLogMapper.class).insert(log);
				}
				r.setState("200");
				r.setMsgInfo("打印标签成功");	
				r.setData(list);
				return r;
			}
		} catch (Exception e) {
			r.setState("500");
			r.setMsgInfo("打印标签失败");
			e.printStackTrace();
			throw new Exception("打印标签失败");
		}
		return r;
	}
	/***
	 * 动作处理--交工按钮    updateCuttingMByprocessNo
	 * @throws Exception 
	 * 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOff( String vPlanNo,String vObjectNoVt ,String vMaterialNo,String vMchCode, String vWrkGrp,String vOprname) throws Exception {
		ResultModel r=new ResultModel();
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		String work_ord = (String) this.getSession().getAttribute(HomeService.SESSION_WORK_ORD);
		String work_grp = (String) this.getSession().getAttribute(HomeService.SESSION_WORK_GRP);
		String work_date = (String) this.getSession().getAttribute(HomeService.SESSION_WORK_TIME);
		work_date = work_date.substring(0, 10);
		String v_ret = "";
		Integer v_cnt;
		Number v_wdt_lower;
		Number v_wdt_upper;
		Number   v_len_lower ;
		Number v_len_upper;
		double v_sum=0;//理重计算值
		
		CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
		
			//1. 验证横剪/开平作业计划主记录存在
			String ifplan = ifplan(vMchCode, vPlanNo);
			if (isEmpty(ifplan) != null) {
				r.setMsgInfo(ifplan);
				r.setState("500");
				return r;
			}
			//2. 验证横剪/开平作业计划明细记录存在
			String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
			if (isEmpty(ifplanDetail) != null) {
				r.setMsgInfo(ifplanDetail);
				r.setState("500");
				return r;
			}

	     	// 3.验证虚拟物料表中，原料卷计划信息存在
			PlnMaterielDetail pmd=new PlnMaterielDetail();
			pmd.setObject_no_vt(vObjectNoVt);
			int count3 = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
			if (count3<=0) {
				r.setMsgInfo("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
				r.setState("500");
				return r;
			}
			// 4.验证虚拟物料表中，板垛计划信息存在
			PlnMaterielDetail detail = new PlnMaterielDetail();
			detail.setMat_object_no_vt(vObjectNoVt);
			v_cnt = this.getBean(PlnMaterielDetailMapper.class).count(detail);
			if (v_cnt <= 0) {
				v_ret = ("虚拟卷号：" + vObjectNoVt + "板垛虚拟物料信息不存在！");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}

			// 5.验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态
			String notFinsh = isNotFinsh(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
			if (isEmpty(notFinsh)!= null) {
				r.setMsgInfo(notFinsh);
				r.setState("500");
				return r;
			}
			MesCrCrossCuttingM m = new MesCrCrossCuttingM();
			m.setMachine_code(vMchCode);
			m.setSchedule_no(vPlanNo);
			m.setMaterial_no_vt(vObjectNoVt);
			m.setMaterial_no(vMaterialNo);
			List<MesCrCrossCuttingM> v_rec_ccm = this.getBean(MesCrCrossCuttingMMapper.class).findWithCondition(m, null,null, 0, 0);
			if (v_rec_ccm.get(0).getHand_over_status() != null
					&& !v_rec_ccm.get(0).getHand_over_status().equals("0")) {
				v_ret = ("原料卷号："+vMaterialNo+"当前已生产交工，不能重复操作！");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}
			if (v_rec_ccm.get(0).getMtr_thr_wgt() == null || v_rec_ccm.get(0).getMtr_thr_wgt() < 0){																																					
			    v_ret = "原料卷号："+vMaterialNo+"，原卷重量为空或小于0，无法计算板垛理重！";																																					
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;																																						
			 }																																						
			
			
			// 6.、验证原料卷，当前已有板垛实绩
			MesCrCrossCuttingD mcccd=new MesCrCrossCuttingD();
			mcccd.setProcess_no(v_rec_ccm.get(0).getProcess_no());
			int count = this.getMapper(MesCrCrossCuttingDMapper.class).count(mcccd);
			if (count <= 0) {
				v_ret = "原料卷号：" + vMaterialNo + "无板垛实绩，不能生产交工！";
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}

			// （7）、调用生产管理接口，验证是否能执行相关操作，如果不满足条件，返回错误信息到前端，结束操作（接口由生产管理模块提供）；
			//验证横剪明细表是否是开始开平状态
			PlnCuttolengthPlanDetail pcpd = new PlnCuttolengthPlanDetail();
			pcpd.setCl_plan_no(vPlanNo);
			pcpd.setObject_no_vt(vObjectNoVt);
			List<PlnCuttolengthPlanDetail> pcpdetail = this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(pcpd, 0, 1);
			if (pcpdetail !=null && pcpdetail.size()>0) {
				if (!"5BCL03".equals(pcpdetail.get(0).getStatus())) {
					r.setState("200");
					r.setMsgInfo("原料卷号 :"+vMaterialNo+"未进入作业状态,不能交工!");
					return r;
				}
			}

			// 8 如果产生了部分原卷吊销，则调用物流模块接口，验证吊销卷号在库存中不存在
			if("1".equals(v_rec_ccm.get(0).getPartial_rejected()) && v_rec_ccm.get(0).getRejected_coil_no() !=null){
				YdmProductDetail t=new YdmProductDetail();
				t.setCoilno(v_rec_ccm.get(0).getRejected_coil_no());
				v_cnt=	this.getMapper(YdmProductDetailMapper.class).count(t);
				if(v_cnt>0){
					v_ret = ("吊销卷号：" + v_rec_ccm.get(0).getRejected_coil_no() + " 卷号重复，库存中已存在此卷号！");
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
			}
			
			MesCrCrossCuttingM mcc=new MesCrCrossCuttingM();
			mcc.setProcess_no(v_rec_ccm.get(0).getProcess_no());
			mcc.setWrk_grp(work_grp);
			mcc.setWrk_ord(work_ord);
			mcc.setWrk_date(work_date);
	  		this.getMapper(MesCrCrossCuttingMMapper.class).update(mcc);
	  					
			//更新子表班组
	  		MesCrCrossCuttingD mdd=new MesCrCrossCuttingD();
			mdd.setProcess_no(v_rec_ccm.get(0).getProcess_no());
			List<MesCrCrossCuttingD> lmddq=this.getMapper(MesCrCrossCuttingDMapper.class).findWithCondition(mdd, "", " packing_no ", 0, 0);
			for(MesCrCrossCuttingD mc : lmddq){
				MesCrCrossCuttingD mcsd=new MesCrCrossCuttingD();
	  			mcsd.setPacking_no(mc.getPacking_no());
	  			mcsd.setWrk_grp(work_grp);
	  			mcsd.setWrk_ord(work_ord);
	  			mcsd.setWrk_date(work_date);
	  			this.getMapper(MesCrCrossCuttingDMapper.class).update(mcsd);
			}

			
			
			// 9.获取开平成品允许宽度、长度偏差(mm)上、下限值
			final String code1="386201";
			final String code2="386202";
			final String code3="386301";
			final String code4="386302";
			try {
				// （9.1）、宽度上限	
				v_wdt_upper=this.getMapper(ComBaseInfoMapper.class).selectbaseCode(code1);
			} catch (Exception e) {
				v_wdt_upper=0;
			}
			try {
				// （9.2）、宽度下限
				v_wdt_lower=this.getMapper(ComBaseInfoMapper.class).selectbaseCode(code2);
			} catch (Exception e) {
				v_wdt_lower=0;
			}
			try {
				// 9.3）、长度上限
				v_len_upper=this.getMapper(ComBaseInfoMapper.class).selectbaseCode(code3);
			} catch (Exception e) {
				v_len_upper=0;
			}
			try {
				// 9.4）、长度下限
				v_len_lower=this.getMapper(ComBaseInfoMapper.class).selectbaseCode(code4);
			} catch (Exception e) {
				v_len_lower=0;
			}

			// （10）、逐一循环板垛实绩（废副品物料除外），验证各板垛的 厚、宽、长、实重 都＞0
			List<MesCrCrossCuttingD> listD=	this.getMapper(MesCrCrossCuttingDMapper.class).FindMescrcrDByprocessNo(v_rec_ccm.get(0).getProcess_no());
			for (MesCrCrossCuttingD  cur_01 : listD) {
				if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
					v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板厚度必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
					v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板宽度必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
					v_ret = "板垛号:"+cur_01.getPacking_no()+"钢板长度必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				if(cur_01.getPlate_cnt()==null || cur_01.getPlate_cnt()<=0){
					v_ret = "板垛号："+cur_01.getPacking_no()+"子板块数必须大于0！"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				if(cur_01.getPacking_net_wgt() ==null || cur_01.getPacking_net_wgt() <= 0){
					v_ret = "板垛号:"+cur_01.getPacking_no()+"板垛重量必须大于0!"; 
					r.setMsgInfo(v_ret);
					r.setState("500");
					return r;
				}
				
				v_sum+=cur_01.getAct_wdt()*cur_01.getAct_len()*cur_01.getPlate_cnt();
			}

			
			//捆包数据的处理
			Double v_sum_total=0d;
			Double yuanlai=v_rec_ccm.get(0).getMtr_thr_wgt();
			if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
				MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
				mcccm.setSchedule_no(v_rec_ccm.get(0).getSchedule_no());
				mcccm.setIs_bales(1);
				List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
				
				for(MesCrCrossCuttingM mmm:list_mcc){
					v_sum_total+=mmm.getMtr_thr_wgt();
				}
				v_rec_ccm.get(0).setMtr_thr_wgt(v_sum_total);
			}
			
			// （10'）、逐一循环板垛实绩（废副品物料除外），重新计算各板垛理重值：= 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
			
			List<MesCrCrossCuttingD> lmccd = this.getMapper(MesCrCrossCuttingDMapper.class).doQueryMes(v_rec_ccm.get(0).getProcess_no(),"");
			
//		   for(MesCrCrossCuttingD d:lmccd){
//				if(Integer.parseInt(d.getXh())<Integer.parseInt(d.getCnt())){
//					// （10.1'）、前N-1个板垛理重 = 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
//					this.getMapper(MesCrCrossCuttingDMapper.class).updateMdd(v_sum,d.getPacking_no());
//					
//				}else if(Integer.parseInt(d.getXh())==Integer.parseInt(d.getCnt())){
//					//  （10.2'）、第N个板垛理重 = 原卷理重 - ∑前N-1板垛重量
//					this.getMapper(MesCrCrossCuttingDMapper.class).updateMdd1(v_sum,d.getPacking_no());
//				}
//			}
		   int i=1;
		   double lastWgt=0;
		   for(MesCrCrossCuttingD d:lmccd){
			   // （10.1'）、前N-1个板垛理重 = 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
			   //this.getMapper(MesCrCrossCuttingDMapper.class).updateMdd(v_sum,d.getPacking_no());
				//四舍五入
			   BigDecimal b=null;
			   double f1=0;
			   if(Integer.parseInt(d.getXh())<Integer.parseInt(d.getCnt())){
				   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()*d.getAct_wdt()*d.getAct_len()*d.getPlate_cnt()/v_sum);  
				   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
				   lastWgt+=f1;
			   }else if(Integer.parseInt(d.getXh())==Integer.parseInt(d.getCnt())){
				   b= new BigDecimal(v_rec_ccm.get(0).getMtr_thr_wgt()-lastWgt);  
				   f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
			   }
				MesCrCrossCuttingD mccccd=new MesCrCrossCuttingD();
				mccccd.setPacking_no(d.getPacking_no());
				mccccd.setPacking_thr_wgt(f1);
				this.getMapper(MesCrCrossCuttingDMapper.class).update(mccccd);
				i++;
		   }
			
		   //恢复：
		   v_rec_ccm.get(0).setMtr_thr_wgt(yuanlai);
			
			// （11）、将板垛实绩，与板垛计划，按顺序逐一比较，厚宽长，如果全在运行偏差范围，则挂单，否则脱单
			/*
			 * --（11.1）、板垛实际厚度 = 板垛计划厚度 AND -----------(板垛实际宽度 - 板垛计划宽度) >= 宽度下限
			 * AND -----------(板垛实际宽度 - 板垛计划宽度) <= 宽度上限 AND -----------(板垛实际长度 -
			 * 板垛计划长度) >= 长度下限 AND -----------(板垛实际长度 - 板垛计划长度) <= 长度上限 AND
			 */
			// （11.2）、挂单
			// （11.3）、脱单

				List<CommentDetialAndCuttD> list2= this.getMapper(PlnCuttolengthPlanDetailMapper.class).doQueryDetail(v_rec_ccm.get(0).getProcess_no(), vObjectNoVt);
				if(list2!=null && list2.size()>0){
					for (CommentDetialAndCuttD cur_02 : list2) {
                       if(cur_02.getPacking_no()!=null){
	                    	if(cur_02.getPln_xh()!=null && cur_02.getAct_thk().doubleValue()==cur_02.getPln_thk().doubleValue() &&																																						
										(cur_02.getAct_wdt().doubleValue()- cur_02.getPln_wdt().doubleValue()>= v_wdt_lower.doubleValue()) &&																																							
										((cur_02.getAct_wdt().doubleValue()- cur_02.getPln_wdt().doubleValue()) <= v_wdt_upper.doubleValue()) &&																																							
										((cur_02.getAct_len().doubleValue() - cur_02.getPln_len().doubleValue()) >= v_len_lower.doubleValue())&&																																							
										((cur_02.getAct_len().doubleValue()- cur_02.getPln_len().doubleValue()) <= v_len_upper.doubleValue()) 
										){
								//挂单
								this.getMapper(MesCrCrossCuttingDMapper.class).UpdateBypackingNo(cur_02,"");
							}else{
								//脱单
								this.getMapper(MesCrCrossCuttingDMapper.class).UpdateBypackingNo2(cur_02,"");
							}
                       }
					}
				}
				

				// （12）、如果产生了部分原卷吊销，则调用物流模块接口，将吊销原卷（新卷号）入库（接口由物流模块提供）
				//queryNo:原始卷号;
				//ypdi:吊销卷信息[新卷号Coilno(吊销卷卷号)，长度Length、内径Diameter_inn、外径Diameter_out、理重Theoryweight、实重Factweight]
				if(	v_rec_ccm.get(0).getPartial_rejected().equals("1") && v_rec_ccm.get(0).getRejected_coil_no() !=null){
					//将吊销原卷（新卷号）入库
					YdmProductDetail p=new YdmProductDetail();
					p.setCoilno(v_rec_ccm.get(0).getRejected_coil_no());
					p.setLength(v_rec_ccm.get(0).getPln_mtr_len());
					p.setDiameter_inn(v_rec_ccm.get(0).getPln_mtr_inn_dia());
					p.setDiameter_out(v_rec_ccm.get(0).getPln_mtr_out_dia());
					p.setTheoryweight(v_rec_ccm.get(0).getPln_mtr_thr_wgt());
					p.setFactweight(v_rec_ccm.get(0).getRejected_coil_act_wgt());
					this.getBean(LmsApiServiceImpl.class).doInsertRevoke(vMaterialNo,p);
				}


				
				try{
					
					//2019-02-21
			  		/*
			  		检验批分批规则：
			  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
			  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
			  		 */
				    Map<String, List<MesCrCrossCuttingD>> mc_list =new HashMap<String, List<MesCrCrossCuttingD>>();
			  		if(v_rec_ccm.get(0).getSchedule_no()!=null && !"".equals(v_rec_ccm.get(0).getSchedule_no())){
			  			List<MesCrCrossCuttingM> v_rec_baf_mList = this.getMapper(MesCrCrossCuttingMMapper.class).findWithCondition(null,"schedule_no='"+v_rec_ccm.get(0).getSchedule_no()+"'", null, 0, 0);
			  			List<MesCrCrossCuttingD> mcdlist=new ArrayList<MesCrCrossCuttingD>();
			  			for(MesCrCrossCuttingM mcsttlim:v_rec_baf_mList){
			  				List<MesCrCrossCuttingD> lll = this.getMapper(MesCrCrossCuttingDMapper.class).findWithCondition(null, "process_no='"+v_rec_ccm.get(0).getProcess_no()+"' and packing_no not like '%B'", null, 0, 0);
			  				for(MesCrCrossCuttingD mccc:lll){
			  					mcdlist.add(mccc);	
			  				}
			  			}
			  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
			  					try{
			  						mc_list = groupBillingDataByExcpBatchCode(mcdlist,v_rec_ccm.get(0).getSchedule_no());
			  					}catch(Exception e){
			  						
			  					}
			  			}
			  		}
			  		if(mc_list!=null && mc_list.size()>0){
						for(Map.Entry<String, List<MesCrCrossCuttingD>> grouplist :mc_list.entrySet()){
							List<MesCrCrossCuttingD> listCes = grouplist.getValue();
							for(MesCrCrossCuttingD mcam:listCes){
									MesCrCrossCuttingD mCrossleo = new MesCrCrossCuttingD();
									mCrossleo.setPacking_no(mcam.getPacking_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesCrCrossCuttingDMapper.class).update(mCrossleo);
							}
						}
					}
					
				}catch(Exception e){
					
				}
				
				
				
				
				
				// （13）、逐一循环板垛实绩记录（此处一定要重新获取板垛实绩记录，订单信息可能变化
				List<MesCrCrossCuttingD> listd=this.getMapper(MesCrCrossCuttingDMapper.class).FindMescrcrDByprocessNo1(v_rec_ccm.get(0).getProcess_no());
				for (MesCrCrossCuttingD  cur_03  : listd) {
					//（13.1）、调用物流模块接口，执行板垛入库相关操作（接口由物流模块提供）
					YdmProductDetail p=new YdmProductDetail();
					p.setCoilno(v_rec_ccm.get(0).getRejected_coil_no());
					//入库的信息不全......
					CommonPage<MesCrCrossCuttingD> cp2=new CommonPage<MesCrCrossCuttingD>();
					MesCrCrossCuttingD mcsd=new MesCrCrossCuttingD();
					mcsd.setPacking_no(cur_03.getPacking_no());
					//mcsd.setCoil_no_vt(mcsq.getCoil_no_vt());
					cp2.setObject(mcsd);
					
					//（13.2）、如果是废副品物料，则废副品的净重 packing_net_wgt 必须大于0，才能调用入库接口
					if( cur_03.getPacking_no() != null && "B".equals(cur_03.getPacking_no().substring(cur_03.getPacking_no().length()-1)) ) {
						if(cur_03.getPacking_net_wgt()!=null && cur_03.getPacking_net_wgt()>0){
							//调用物流模块（仓库管理）接口，逐一将分条子卷实绩各子卷，插入库存记录（待入库状态）；	
							try{
								//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
								/**
								 *  MesApiDesignInfoImpl/getNextProcessCode
									 code 当前工序代码 1 分条/2 开平/3 罩退/4 平整
									 object_no_vt 虚拟物料号
									如果下一个工序不存在 则返回 ""
								 */
								cp2.setMemo1("500203");//成品库
								//生产订单统计 统计量并修改生产订单状态
							    try{
							    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(cur_03.getPacking_no(),1,true);
							    }catch(Exception e){
							    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
							    	e.printStackTrace();
							    }
								
								ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doMesIn1(cp2);
								if(!"200".equals(rmValid.getState())){
									throw new Exception("入库出错"+rmValid.getMsgInfo());
								}
							}catch(Exception ex){
								throw new Exception("物流入库接口出错!"+ ex.getMessage());
							}
						}
					}else{
						
						try{
							//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
							/**
							 *  MesApiDesignInfoImpl/getNextProcessCode
								 code 当前工序代码 1 分条/2 开平/3 罩退/4 平整
								 object_no_vt 虚拟物料号
								如果下一个工序不存在 则返回 ""
							 */
							String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("2",vObjectNoVt);
							if(nextProcessCode==null || "".equals(nextProcessCode)){
								cp2.setMemo1("500203");//成品库								
								//生产订单统计 统计量并修改生产订单状态
							    try{
							    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(cur_03.getPacking_no(),1,true);
							    }catch(Exception e){
							    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
							    	e.printStackTrace();
							    }								
							}else{
								cp2.setMemo1("500202");//在制品库
							}
						}catch(Exception ex){
							throw new Exception("获取下道工序异常"+ ex.getMessage());
						}
						//调用物流模块（仓库管理）接口，逐一将分条子卷实绩各子卷，插入库存记录（待入库状态）；	
						try{
							//2019-02-21修改
							/*PlnMaterielDetail pmd_21=new PlnMaterielDetail();
							pmd_21.setObject_no_vt(vObjectNoVt);
							List<PlnMaterielDetail> list_pmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmd_21, 0, 0);
							boolean flag_Ct = false;
							if(list_pmd!=null && list_pmd.size()>0){
								flag_Ct=this.getBean(MesApiDesignInfoImpl.class).getContractType(list_pmd.get(0).getProd_order_no());
							}
							if(flag_Ct){
								cp2.setMemo1("500202");//在制品库
								cp2.setMemo3("507101");//物料属性，优特钢带
							}*/
							
							ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doMesIn1(cp2);
							if(!"200".equals(rmValid.getState())){
								throw new Exception("入库出错"+rmValid.getMsgInfo());
							}
						}catch(Exception ex){
							throw new Exception("物流入库接口出错!"+ ex.getMessage());
						}
					}
					// 2019-09-23 panbin 增加校验质量判定结果,空则不允许交工 
					ResultModel tmp_rst = 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);
					try {
						tmp_rst = this.getBean(MesApiServiceImpl.class).hasJudegeResult(cur_03.getPacking_no(),cur_03.getProd_order_no(),processpoint.cross_cutting_code);
					} catch(Exception ex) {
						throw new Exception("获取质量判定信息接口报错!"+ ex.getMessage());
					}
					if(!"200".equals(tmp_rst.getState())){
						throw new Exception(tmp_rst.getData().toString());
					}
					
					try{
						ResultModel rmxx = this.getBean(QmsApiServiceImpl.class).doQueryJudegeResult(cur_03.getPacking_no());
						if(rmxx!=null && rmxx.getData()!=null && (rmxx.getData() instanceof JudgeResult)){
							JudgeResult jr=(JudgeResult)rmxx.getData();
							YdmProductDetail ypd=new YdmProductDetail();
							ypd.setCoilno(cur_03.getPacking_no());
							boolean falgggg=false;
							if(jr.getMarginal_result()!=null){
								ypd.setMarginal_result(jr.getMarginal_result());
								falgggg=true;
							}
							if(jr.getMarginal_result_id()!=null){
								ypd.setMarginal_result_id(jr.getMarginal_result_id());
								falgggg=true;
							}
							if(jr.getMeasure_result()!=null){
								ypd.setMeasure_result(jr.getMeasure_result());
								falgggg=true;
							}
							if(jr.getMeasure_result_id()!=null){
								ypd.setMeasure_result_id(jr.getMeasure_result_id());
								falgggg=true;
							}
							if(jr.getSfd_is_lock()!=null){
								ypd.setSfd_is_lock(jr.getSfd_is_lock());
								falgggg=true;
							}
							if(jr.getSfe_is_lock()!=null){
								ypd.setSfe_is_lock(jr.getSfe_is_lock());
								falgggg=true;
							}
							if(jr.getSfu_is_lock()!=null){
								ypd.setSfu_is_lock(jr.getSfu_is_lock());
								falgggg=true;
							}
							if(jr.getSic_is_lock()!=null){
								ypd.setSic_is_lock(jr.getSic_is_lock());
								falgggg=true;
							}
							if(jr.getSizeResult()!=null){
								ypd.setSizeresult(jr.getSizeResult());
								falgggg=true;
							}
							if(jr.getUd_surface_result()!=null){
								ypd.setUd_surface_result(jr.getUd_surface_result());
								falgggg=true;
							}
							if(jr.getUd_surface_result_id()!=null){
								ypd.setUd_surface_result_id(jr.getUd_surface_result_id());
								falgggg=true;
							}
							if(jr.getUp_surface_result()!=null){
								ypd.setUp_surface_result(jr.getUp_surface_result());
								falgggg=true;
							}
							if(jr.getUp_surface_result_id()!=null){
								ypd.setUp_surface_result_id(jr.getUp_surface_result_id());
								falgggg=true;
							}
							if(jr.getUp_surface_flaw() != null) {
								ypd.setUp_surface_flaw(jr.getUp_surface_flaw());
								falgggg= true;
							}
							if(jr.getUd_surface_flaw() != null) {
								ypd.setUd_surface_flaw(jr.getUd_surface_flaw());
								falgggg= true;
							}
							if(jr.getMarginal_flaw()!= null) {
								ypd.setMarginal_flaw(jr.getMarginal_flaw());
								falgggg= true;
							}
							if(falgggg){
//								this.getMapper(YdmProductDetailMapper.class).update(ypd);
							}
						}
					}catch(Exception e){
						System.out.println("调用质量接口报错");
						e.printStackTrace();
					}
					
					try{
					    if (cur_03.getPacking_no() != null && "B".equals(cur_03.getPacking_no().substring(cur_03.getPacking_no().length()-1))){
							//则调用生产管理的【分条完成——实物 生成接口】 2018-06-22
							PrcMaterielRelation pmr=new PrcMaterielRelation();
							pmr.setObject_no(v_rec_ccm.get(0).getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
							pmr.setSub_object_no(cur_03.getPacking_no());//MES_CR_SLITTING_D表的子卷号
							pmr.setRelation_seq(3);
							this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_PrcMatRelAdd(pmr);//有insert插入prc_materiel_relation的操作
	
					    }else{
					    	
					    	if(cur_03.getPacking_no_vt() !=null){
								//13.3满足计划，则调用生产管理接口：【横剪/开平完成——虚拟板垛 挂料接口】（接口由生产管理模块提供）
								PlnMaterielDetail m2=new PlnMaterielDetail();
								
								m2.setSub_object_no(cur_03.getPacking_no());
								m2.setObject_no(v_rec_ccm.get(0).getMaterial_no());
								m2.setObject_no_vt(cur_03.getPacking_no_vt());
								this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_Relation(m2); 
								}else{
									
									//如果此子卷的虚拟子卷号为空（COIL_NO_VT，即为非计划）   ？？
									PlnMaterielDetail pmdq=new PlnMaterielDetail();
									pmdq.setObject_no(v_rec_ccm.get(0).getMaterial_no());
									pmdq.setMaterial_no(v_rec_ccm.get(0).getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
									pmdq.setSub_object_no(cur_03.getPacking_no());//MesCrCrossCuttingD表的子卷号
									pmdq.setCreate_time(cur_03.getCreate_time());
									this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttolengthFinsh_No_Plan(pmdq);
								}
					    	
					    }
					}catch(Exception ex){
						throw new Exception("计划接口出错!"+ ex.getMessage());
					}
				    
				    
				  //=======================质量检验委托开始=============================
				    if(v_rec_ccm.get(0).getSchedule_no()!=null && !"".equals(v_rec_ccm.get(0).getSchedule_no())){//作业计划号不为空
				    	try{
							QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
							PlnMaterielDetail pmdq=new PlnMaterielDetail();
							pmdq.setObject_no_vt(vObjectNoVt);
							List<PlnMaterielDetail> lpmdq22=this.getMapper(PlnMaterielDetailMapper.class).find(pmdq, 0, 1);
							String prod_order_no=lpmdq22.get(0).getProd_order_no();
							List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).findWithCondition(null, "prod_order_no='"+prod_order_no+"'", null, 0, 0);
							if(lpp!=null && lpp.size()>0){
								int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(vObjectNoVt, "D");
								// 获取工艺路径包含成分或者材质类
								if(judge_Contain_Qcm!=-1){
									ajsfp.setPline_seq((long)judge_Contain_Qcm);
									
							  		ajsfp.setInspection_lot(cur_03.getInspection_lot());//检验号
									ajsfp.setBatch_no(v_rec_ccm.get(0).getSchedule_no());//轧批号    炉次号
									//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
									List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
									if(list_plnP!=null && list_plnP.size()>0){
										ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
									}
									
									ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
									//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
									//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
									//ajsfp.setHeat_no(mcm.getBatch_no());//炉号      
									//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
									ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
									ajsfp.setMaterial_no(cur_03.getPacking_no());//取样材料号   
									ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
									ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
									ajsfp.setBoard_no(v_rec_ccm.get(0).getMaterial_no());
									
									ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_ccm.get(0).getMachine_code());
									ComBasePline cbp = this.getMapper(ComBasePlineMapper.class).findById(cbm.getPline_code());
									ajsfp.setPline_code(cbm.getPline_code());//产线代码
									ajsfp.setPline_name(cbp.getPline_name());// 产线名称
									//后期需要修改
									ajsfp.setProcess_code("D");//工序代码    com_base_process表
									ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
									//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
									List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
									lqsfp.add(ajsfp);
									CommonPage<QcmJhySampleFromPlan>  cpqjsfp=new CommonPage<QcmJhySampleFromPlan>();
									cpqjsfp.setObjectList(lqsfp);
//									if(mesCrSlittingM.getSchedule_no()!=null && mesCrSlittingM.getSchedule_no()!=null && mesCrSlittingM.getSchedule_no()!=null){
//										if(!v_rec_cam.getBatch_no().equals(mcm.getBatch_no())){
//											QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
//											qjsprem.setDesign_key(lpp.get(0).getDesign_key());
//											qjsprem.setInspection_lot(v_rec_cam.getInspection_lot());
//											CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
//											sum22.setObject(qjsprem);
//											this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
//										}
//									}
									ResultModel reModel = this.getBean(QcmJhySampleConsignDItemServiceImpl.class).AutoGenerationSampleInfo(cpqjsfp);
									if(reModel!=null){
										System.out.println(reModel.getState());
										System.out.println(reModel.getMsgInfo());
									}
								}
							}
						}catch(Exception e){
							e.printStackTrace();
						}
				    }
					//==========================质量检验委托结束==================================
				    
				  
				    
				    
				}
				// 开平完成 虚拟母卷统计
				PlnMaterielDetail pmdq=new PlnMaterielDetail();
				pmdq.setObject_no_vt(vObjectNoVt);
				List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).find(pmdq, 0, 1);
				try{
					this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_Sum(lpmdq.get(0));
				}catch(Exception ex){
					throw new Exception("计划接口出错!"+ ex.getMessage());
				}
				
				// （14）、修改开平作业主实绩交工状态
				this.getMapper(MesCrCrossCuttingMMapper.class).updateCuttingMByprocessNo(vOprname, v_rec_ccm.get(0).getProcess_no());  
			
				//捆包数据的处理
				if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
					MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
					mcccm.setSchedule_no(v_rec_ccm.get(0).getSchedule_no());
					mcccm.setIs_bales(1);
					List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
					for(MesCrCrossCuttingM mmm:list_mcc){
						if(mmm.getMaterial_no().equals(v_rec_ccm.get(0).getMaterial_no())){
							continue;
						}
						//this.getMapper(MesCrCrossCuttingMMapper.class).updateCuttingMByprocessNo(vOprname, mmm.getProcess_no());  
						MesCrCrossCuttingM m_main_plan = this.getMapper(MesCrCrossCuttingMMapper.class).findById(v_rec_ccm.get(0).getProcess_no());
						MesCrCrossCuttingM mccleo=new MesCrCrossCuttingM();
						mccleo.setProcess_no(mmm.getProcess_no());
						mccleo.setHand_over_status("1");
						mccleo.setHand_over_time(new Date());
						mccleo.setHand_over_opr(vOprname);
						mccleo.setWrk_date(m_main_plan.getWrk_date());
						mccleo.setWrk_grp(m_main_plan.getWrk_grp());
						mccleo.setWrk_ord(m_main_plan.getWrk_ord());
						mccleo.setUpdate_opr(vOprname);
						mccleo.setUpdate_time(new Date());
						this.getMapper(MesCrCrossCuttingMMapper.class).update(mccleo);
						
						PlnCuttolengthPlanDetail pcpdxxx=new PlnCuttolengthPlanDetail();
						pcpdxxx.setStatus("5BCL10");
						pcpdxxx.setCl_plan_no(mmm.getSchedule_no());
						pcpdxxx.setObject_no(mmm.getMaterial_no());
						this.getMapper(PlnCuttolengthPlanDetailMapper.class).doUpdatee(pcpdxxx);
						//2018-05-05新增实物跟踪 //调用生产计划模块物料跟踪接口 
						PrcMaterielProcess pmp=new PrcMaterielProcess();
						pmp.setPrc_code("5BCL10");//开平完成状态
						pmp.setCreate_time(new Date());//来源.
						pmp.setObject_no(mmm.getMaterial_no());
						pmp.setCreate_man_name(vOprname);
						pmp.setRemark("捆包交工完成");
						//新增物料跟踪
						int tmp= this.getBean(MesApiServiceImpl.class).INSERT_OBJ_PROCESS(pmp);
						if(tmp==-1){
						throw new Exception("捆包物料跟踪失败");
						}
						
					}
				}
				
				
				r.setState("200");
				r.setMsgInfo("交工成功");
			
		return r;
	}
	
	
	/**
	 *  同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		检验批号编码规则：炉次号+两位流水号，示例：2619000401）
	 * @param billingList
	 * @return
	 * @throws Exception
	 */
	private Map<String, List<MesCrCrossCuttingD>> groupBillingDataByExcpBatchCode(List<MesCrCrossCuttingD> billingList,String schedule) throws Exception{
		Map<String, List<MesCrCrossCuttingD>> resultMap = new HashMap<String, List<MesCrCrossCuttingD>>();
		try{
			int i=0;
			Integer max=this.getMapper(MesCrAnnealMMapper.class).findMaxIns3mm(schedule);
			if(max!=null){
				i=max;
			}
			for(MesCrCrossCuttingD tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"K"+tmExcpNew.getAct_thk()+"K"+tmExcpNew.getAct_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
//					i++;
//					String inspection_lot=schedule+lpad(i+"", 2, "0");
					List<MesCrCrossCuttingD> list = resultMap.get(key);
					if(list!=null && list.size()>0){
						tmExcpNew.setInspection_lot(list.get(0).getInspection_lot());
					}
					resultMap.get(key).add(tmExcpNew);
				}else{//map中不存在，新建key，用来存放数据
					i++;
					String inspection_lot=schedule+lpad(i+"", 2, "0");
					tmExcpNew.setInspection_lot(inspection_lot);
					List<MesCrCrossCuttingD> tmpList = new ArrayList<MesCrCrossCuttingD>();
					tmpList.add(tmExcpNew);
					resultMap.put(key, tmpList);
				}
 
			}
		}catch(Exception e){
			 System.out.println("炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号进行分组时出现异常");
			 return resultMap;
		}
		return resultMap;
	}
	

	/***
	 * 动作处理--取消交工按钮     完成
	 * @throws Exception 
	 * 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOutOff(String vPlanNo,String vObjectNoVt ,String vMaterialNo,String vMchCode,
			String vWrkGrp,String vOprname) throws Exception {
		ResultModel r=new ResultModel();
		vOprname = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(vOprname==null){
			vOprname="";
		}
		String v_ret = "";
		Integer v_cnt;
		
			//1. 验证横剪/开平作业计划主记录存在
			String ifplan = ifplan(vMchCode, vPlanNo);
			if (isEmpty(ifplan) != null) {
				r.setMsgInfo(ifplan);
				r.setState("500");
				return r;
			}
			//2 验证横剪/开平作业计划明细记录存在
			String ifplanDetail = ifplanDetail(vMchCode, vPlanNo, vObjectNoVt, vMaterialNo);
			if (isEmpty(ifplanDetail) != null) {
				r.setMsgInfo(ifplanDetail);
				r.setState("500");
				return r;
			}
			//（3）、验证虚拟物料表中，原料卷计划信息存在
			PlnMaterielDetail pmd=new PlnMaterielDetail();
			pmd.setObject_no_vt(vObjectNoVt);
			int count3 = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
			if (count3<=0) {
				r.setMsgInfo("虚拟卷号："+vObjectNoVt+"\n原料卷虚拟物料信息不存在！");
				r.setState("500");
				return r;
			}
			//（4）、验证虚拟物料表中，板垛计划信息存在
			PlnMaterielDetail detail = new PlnMaterielDetail();
			detail.setMat_object_no_vt(vObjectNoVt);
			v_cnt = this.getBean(PlnMaterielDetailMapper.class).count(detail);
			if (v_cnt <= 0) {
				v_ret = "虚拟卷号：" + vObjectNoVt + "板垛虚拟物料信息不存在！";
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}

			//5.验证原料卷对应的横剪/开平主实绩存在，且为“已交工”状态mes_cr_cross_cutting_m
			MesCrCrossCuttingM m = new MesCrCrossCuttingM();
			m.setMachine_code(vMchCode);
			m.setSchedule_no(vPlanNo);
			m.setMaterial_no_vt(vObjectNoVt);
			m.setMaterial_no(vMaterialNo);
			v_cnt = this.getMapper(MesCrCrossCuttingMMapper.class).count(m);
			if (v_cnt <= 0) {
				v_ret = ("原料卷号：" + vMaterialNo + "当前不存在开平作业主实绩，请确认是否已操作上料！");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}

			List<MesCrCrossCuttingM> v_rec_ccm = this.getBean(
					MesCrCrossCuttingMMapper.class).findWithCondition(m,
							null, null, 0, 0);
			if (v_rec_ccm.get(0).getHand_over_status() != null
					&& !v_rec_ccm.get(0).getHand_over_status().equals("1")) {
				v_ret = ("原料卷号：" + vMaterialNo + "还未生产交工");
				r.setMsgInfo(v_ret);
				r.setState("500");
				return r;
			}

			//6.验证原料卷，当前已有板垛实绩
			v_cnt = this.getMapper(MesCrCrossCuttingDMapper.class)
					.findByProcessNo(v_rec_ccm.get(0).getProcess_no());
			if (v_cnt <= 0) {
				v_ret = ("原料卷号：" + vMaterialNo + " 无板垛实绩!");
				r.setMsgInfo(v_ret);
				r.setState("500");
			}
			//7 第七步不要了 潘斌6-19
			
			//（8）、调用物流模块接口，逐一验证各板垛为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；
			List<MesCrCrossCuttingD> d=  this.getMapper(MesCrCrossCuttingDMapper.class).findWithCondition(null, " process_no = '"+v_rec_ccm.get(0).getProcess_no()+"'", " packing_no ", 0, 0);
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			YdmProductDetail u=new YdmProductDetail();
			for (MesCrCrossCuttingD cur_01 : d) {
				//逐一验证各板垛为待入库状态（可撤销或删除库存数据）
			    u.setCoilno(cur_01.getPacking_no()); 
			    cp.setObject(u);
			    if(
			    		cur_01.getPacking_no() != null 
			    		&& "B".equals(cur_01.getPacking_no().substring(cur_01.getPacking_no().length()-1)) 	
			    	){
			    	
			    }else {
					ResultModel rm1 = this.getBean(LmsApiServiceImpl.class).doConfirmWaitIn(cp);
					if(rm1.getState().equals("500")){
						return rm1;
					}
			    }
			}

			//2018-09-28  是库存状态
			//（9）、如果产生了部分原卷吊销，则调用物流模块接口，验证吊销卷号为待入库状态（  是库存状态
			//可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；
//			CommonPage<YdmProductDetail> cp2=new CommonPage<YdmProductDetail>();
//			if(	v_rec_ccm.get(0).getPartial_rejected().equals("1") && v_rec_ccm.get(0).getRejected_coil_no() !=null){
//				//验证吊销卷号为待入库状态
//				YdmProductDetail u3=new YdmProductDetail();
//				u3.setCoilno(v_rec_ccm.get(0).getRejected_coil_no());
//				cp2.setObject(u3);
//				ResultModel rm2 = this.getBean(LmsApiServiceImpl.class).doConfirmWaitIn(cp2);
//				if(rm2.getState().equals("500")){
//					return rm2;
//				}
//			}

			
			//12）、逐一循环板垛实绩记录	
			//12.1）、满足计划，则调用生产管理接口：【撤销横剪/开平——虚拟板垛 挂料接口】（接口由生产管理模块提供）	
			//（12.2）、非计划，则调用生产管理接口：【横剪/开平——虚拟板垛 释放接口】（接口由生产管理模块提供）
			for (MesCrCrossCuttingD cur_03 : d) {
				//如果此板剁的虚拟板剁号不为空（packing_no_vt，即满足切割计划）
//				if(cur_03.getPacking_no_vt() != null){
//					//则调用生产管理的【开平完成——虚拟子卷 挂料接口】
//					PlnMaterielDetail pmdq=new PlnMaterielDetail();
//					pmdq.setObject_no(cur_03.getPacking_no());
//					pmdq.setObject_no_vt(cur_03.getPacking_no_vt());
//					this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_RelationCancel(pmdq);
//				}else{//如果此板剁的虚拟板剁号为空（packing_no_vt，即为非计划）
//					//则调用生产管理的【开平完成——实物 生成接口】
//					PrcMaterielRelation pmr=new PrcMaterielRelation();
//					pmr.setObject_no(vMaterialNo);
//					pmr.setSub_object_no(cur_03.getPacking_no());
//					this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_PrcMatRelRemove(pmr);
//				}
				try{
					// 如果子堆垛是边丝,则按非计划执行,其余都按计划执行------------------2018-07-09-------------------
					if (cur_03.getPacking_no() != null && "B".equals(cur_03.getPacking_no().substring(cur_03.getPacking_no().length()-1))){
						if (cur_03.getPacking_net_wgt()!=null && cur_03.getPacking_net_wgt().intValue()>0) {
						//则调用生产管理的【撤销开平 实物 撤销生成接口 产生实物，未挂上单时调用】 2018-07-09
						PrcMaterielRelation pmr=new PrcMaterielRelation();
						pmr.setObject_no(vMaterialNo);//投料卷号 material_no   由页面交工按钮传入
						pmr.setSub_object_no(cur_03.getPacking_no());//MES_CR_SLITTING_D表的子卷号
						this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_PrcMatRelRemove(pmr);
						}
					}else {
						//则调用生产管理的【撤销开平 虚拟子堆垛 挂料接口】
						PlnMaterielDetail pmdq=new PlnMaterielDetail();
						pmdq.setObject_no(cur_03.getPacking_no());
						pmdq.setObject_no_vt(cur_03.getPacking_no_vt());
						this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_RelationCancel(pmdq);
						
					}
				}catch(Exception ex){
					throw new Exception("计划接口出错!"+ ex.getMessage());
				}
				
				
				 //=======================质量检验委托开始=============================
			    if(v_rec_ccm.get(0).getSchedule_no()!=null && !"".equals(v_rec_ccm.get(0).getSchedule_no())){//作业计划号不为空
			    	if (cur_03.getPacking_no() !=null && "B".equals(cur_03.getPacking_no().substring(cur_03.getPacking_no().length()-1))) {
		  				if (cur_03.getPacking_net_wgt()==null || cur_03.getPacking_net_wgt().intValue()<=0) {
		  					continue;
		  				}
		  			}
			    	try{
						QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
						PlnMaterielDetail pmdq=new PlnMaterielDetail();
						pmdq.setObject_no_vt(vObjectNoVt);
						List<PlnMaterielDetail> lpmdq22=this.getMapper(PlnMaterielDetailMapper.class).find(pmdq, 0, 1);
						String prod_order_no=lpmdq22.get(0).getProd_order_no();
						List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).findWithCondition(null, "prod_order_no='"+prod_order_no+"'", null, 0, 0);
						if(lpp!=null && lpp.size()>0){
						    
							int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(vObjectNoVt, "D");
							// 获取工艺路径包含成分或者材质类
							if(judge_Contain_Qcm!=-1){
								ajsfp.setPline_seq((long)judge_Contain_Qcm);
								
						  		ajsfp.setInspection_lot(cur_03.getInspection_lot());//检验号
								ajsfp.setBatch_no(v_rec_ccm.get(0).getSchedule_no());//轧批号    炉次号
								//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
								List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
								if(list_plnP!=null && list_plnP.size()>0){
									ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
								}
								ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
								//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
								//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
								//ajsfp.setHeat_no(mcm.getBatch_no());//炉号      
								//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
								ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
								ajsfp.setMaterial_no(cur_03.getPacking_no());//取样材料号   
								ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
								ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
								
								ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_ccm.get(0).getMachine_code());
								ComBasePline cbp = this.getMapper(ComBasePlineMapper.class).findById(cbm.getPline_code());
								ajsfp.setPline_code(cbm.getPline_code());//产线代码
								ajsfp.setPline_name(cbp.getPline_name());// 产线名称
								//后期需要修改
								ajsfp.setProcess_code("D");//工序代码    com_base_process表
								ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
								//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
								List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
								lqsfp.add(ajsfp);
								CommonPage<QcmJhySampleFromPlan>  cpqjsfp=new CommonPage<QcmJhySampleFromPlan>();
								cpqjsfp.setObjectList(lqsfp);
								
								QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
								qjsprem.setDesign_key(lpp.get(0).getDesign_key());
								qjsprem.setInspection_lot(cur_03.getInspection_lot());
								CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
								sum22.setObject(qjsprem);
								this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
//								ResultModel reModel = this.getBean(QcmJhySampleConsignDItemServiceImpl.class).AutoGenerationSampleInfo(cpqjsfp);
//								if(reModel!=null){
//									System.out.println(reModel.getState());
//									System.out.println(reModel.getMsgInfo());
//								}
							}
						}
					}catch(Exception e){
						e.printStackTrace();
					}
			    }
				//==========================质量检验委托结束==================================
				
			    String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("2",vObjectNoVt);
				if(nextProcessCode==null || "".equals(nextProcessCode)){
					 //生产订单统计 统计量并修改生产订单状态
				    try{
				    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(cur_03.getPacking_no(),1,false);
				    }catch(Exception e){
				    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
				    	e.printStackTrace();
				    }
				}
			    
				
				
			}
			//撤销开平 撤销虚拟母卷统计------------------------2018-07-09---------------------------------
			PlnMaterielDetail pmdq=new PlnMaterielDetail();
			pmdq.setObject_no_vt(vObjectNoVt);
			List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).find(pmdq, 0, 1);
			try{
				this.getBean(MesApiCrCrossCuttingMServiceImpl.class).CuttoLengthFinsh_SumCancel(lpmdq.get(0));
			}catch(Exception ex){
				throw new Exception("计划接口出错!"+ ex.getMessage());
			}
			
			
			//10）、调用物流模块接口，逐一删除各板垛库存实绩（接口由物流模块提供）；
			YdmProductDetail u2=new YdmProductDetail();
			CommonPage<YdmProductDetail> cp3=new CommonPage<YdmProductDetail>();
			boolean falg=true;
			try{
				for (MesCrCrossCuttingD cur_01 : d) {
					u2.setCoilno(cur_01.getPacking_no());
					cp3.setObject(u2);
					
					 if(
					    		cur_01.getPacking_no() != null 
					    		&& "B".equals(cur_01.getPacking_no().substring(cur_01.getPacking_no().length()-1)) 	
					    	){
						 YdmProductDetail ypd =new YdmProductDetail();
						 ypd.setCoilno(cur_01.getPacking_no());
						 List<YdmProductDetail> lypd = this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
						 if(lypd!=null && lypd.size()>0){
							 this.getBean(LmsApiServiceImpl.class).doCancelIn(cp3);
						 }
					 }else{
						    this.getBean(LmsApiServiceImpl.class).doCancelIn(cp3);
					 }
					
				}
			}catch(Exception ex){
				throw new Exception("物流撤销入库接口出错!"+ ex.getMessage());
			}
			

			//（11）、如果产生了部分原卷吊销，则调用物流模块接口，删除吊销卷号库存实绩（接口由物流模块提供）
			if(v_rec_ccm.get(0).getPartial_rejected().equals("1") && v_rec_ccm.get(0).getRejected_coil_no() !=null){
				//删除吊销卷号库存实绩
				//this.getBean(LmsApiServiceImpl.class).doInsertRevokeCanl(vMaterialNo);
				ResultModel rm3 = this.getBean(LmsApiServiceImpl.class).doInsertRevokeCanl(v_rec_ccm.get(0).getRejected_coil_no());
				if(rm3.getState().equals("500")){
					//return rm3;
					throw new Exception(rm3.getMsgInfo());
				}
			}
			//（13）、清空所有板垛实绩的虚拟板垛号、生产订单号、订单号信息
			this.getMapper(MesCrCrossCuttingDMapper.class).updateCuttingDAll(vOprname, v_rec_ccm.get(0).getProcess_no());
			//（14）、修改开平作业主实绩交工状态
			this.getMapper(MesCrCrossCuttingDMapper.class).updateCuttingDAll2(vOprname, v_rec_ccm.get(0).getProcess_no());
			
			//捆包数据的处理
			if(v_rec_ccm.get(0).getIs_main_plan()!=null && v_rec_ccm.get(0).getIs_main_plan().intValue()==1){
				MesCrCrossCuttingM mcccm=new MesCrCrossCuttingM();
				mcccm.setSchedule_no(v_rec_ccm.get(0).getSchedule_no());
				mcccm.setIs_bales(1);
				List<MesCrCrossCuttingM> list_mcc = this.getMapper(MesCrCrossCuttingMMapper.class).find(mcccm, 0, 0);
				for(MesCrCrossCuttingM mmm:list_mcc){
					if(mmm.getMaterial_no().equals(v_rec_ccm.get(0).getMaterial_no())){
						continue;
					}
					this.getMapper(MesCrCrossCuttingDMapper.class).updateCuttingDAll2(vOprname, mmm.getProcess_no());

					PlnCuttolengthPlanDetail pcpdxxx=new PlnCuttolengthPlanDetail();
					pcpdxxx.setStatus("5BCL03");
					pcpdxxx.setCl_plan_no(mmm.getSchedule_no());
					pcpdxxx.setObject_no(mmm.getMaterial_no());
					this.getMapper(PlnCuttolengthPlanDetailMapper.class).doUpdatee(pcpdxxx);
					
					// 撤销实物进程跟踪调用生产计划模块物料跟踪撤销接口
					PrcMaterielProcess pmp=new PrcMaterielProcess();
					pmp.setObject_no(mmm.getMaterial_no());
					pmp.setPrc_code("5BCL10");//开始开平的状态
					pmp.setRemark("捆包取消交工");
					pmp.setKeep_sametime_status(0);
					//撤销实物物料状态跟踪函数:
					String tmp=this.getBean(MesApiServiceImpl.class).ARRAYLIST(pmp).getState();
					
				}
			}
			
			r.setState("200");
			r.setMsgInfo("取消交工成功");
		return r;
	}
	//	----------------------------------------------------------横剪计划编制--------------------------------------------------

	//	--------------p b
	/**
	 * 查询待编制计划钢卷
	 * memo1 1为计划时间 2为交货时间
	 * memo2 外径下限值
	 * memo3 外径上限值
	 * memo4 横剪计划号
	 * */
	public ResultModel doQueryWaitPlanWeb(CommonPage<PlnCuttolengthDsnMain> sum){
		ResultModel rm=new ResultModel();
		try{
			// 工序点信息
			ComBaseInfo infoI = this.getMapper(ComBaseInfoMapper.class).findById("200202");
			String sWhere1="",sWhere2="",sWhere3="";
			//假如为1则为计划时间  为2交货时间 4订单接收时间
			if("2".equals(sum.getMemo1())){
				sWhere1+=" and t3.deliver_date between to_date('"+sum.getStartTime()+"','yyyy-MM-dd HH24:mi:ss') and to_date('"+sum.getEndTime()+"','yyyy-MM-dd HH24:mi:ss') ";
			}else if ("4".equals(sum.getMemo1())) {
				sWhere1+=" and t3.create_time between to_date('"+sum.getStartTime()+"','yyyy-MM-dd HH24:mi:ss') and to_date('"+sum.getEndTime()+"','yyyy-MM-dd HH24:mi:ss') ";
			}

			if(sum.getMemo2()!=null&&!"".equals(sum.getMemo2())){
				sWhere3+=" and t1.diameter_out>="+sum.getMemo2();
			}
			if(sum.getMemo3()!=null&&!"".equals(sum.getMemo3())){
				sWhere3+=" and t1.diameter_out<="+sum.getMemo3();
			}
			if(sum.getMemo4()!=null&&!"".equals(sum.getMemo4().trim())){
				sWhere3+=" and t1.cl_plan_no like '%"+sum.getMemo4().trim()+"%'";
			}

			PlnCuttolengthDsnMain pdm=(sum.getObject()==null?(new PlnCuttolengthDsnMain()):sum.getObject());
			if(sum.getObject()!=null){
				//条件2
				if(sum.getObject().getOrder_no()!=null
						&&!"".equals(sum.getObject().getOrder_no().trim())){
					sWhere2+=" and t2.order_no like '%"+sum.getObject().getOrder_no().trim()+"%' ";
				}
				if(sum.getObject().getProd_order_no()!=null
						&&!"".equals(sum.getObject().getProd_order_no().trim())){
					sWhere2+=" and t2.prod_order_no like '%"+sum.getObject().getProd_order_no().trim()+"%' ";
				}
			}
			rm.setData(this.getMapper(PlnCuttolengthDsnMainMapper.class).doQueryWaitPlan(sWhere1, sWhere2, sWhere3,pdm,infoI.getMemo()));
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("服务器异常,请联系管理员！");
			rm.setErrorInfo(ex.getMessage());
		}
		return rm;
	}

	// 调整计划序号 2018-12-18
	// 表计划旧 计划号-顺序号
	Map<String, Integer> v_planno_old = new HashMap<String, Integer>();
		
	/**
	 * 查询已编制横剪计划
	 * memo1 1为计划时间 2为交货时间 3 生产时间
	 * memo2 外径下限值
	 * memo3 外径上限值
	 * memo4 横剪计划号
	 * */
	public ResultModel doQueryCompletePlanWeb(CommonPage<PlnCuttolengthDsnMain> sum){
		ResultModel rm=new ResultModel();
		v_planno_old.clear();
		try{
			StringBuffer sWhere0 = new StringBuffer();
			StringBuffer sWhere1 = new StringBuffer();
			StringBuffer sWhere2 = new StringBuffer();
			StringBuffer sWhere3 = new StringBuffer();
			//假如为1则为计划时间  为2交货时间 3生产时间
			if("1".equals(sum.getMemo1())){
				sWhere0.append(" and t6.send_date between to_date('"+sum.getStartTime()+"','yyyy-MM-dd HH24:mi:ss') and to_date('"+sum.getEndTime()+"','yyyy-MM-dd HH24:mi:ss') ");
			}else if("2".equals(sum.getMemo1())){
				sWhere1.append(" and p.deliver_date between to_date('"+sum.getStartTime()+"','yyyy-MM-dd HH24:mi:ss') and to_date('"+sum.getEndTime()+"','yyyy-MM-dd HH24:mi:ss') ");
			}else if ("3".equals(sum.getMemo1())) {
				sWhere1.append(" and ttt.feeding_time between to_date('"+sum.getStartTime()+"','yyyy-MM-dd HH24:mi:ss') and to_date('"+sum.getEndTime()+"','yyyy-MM-dd HH24:mi:ss') ");
			}else if ("4".equals(sum.getMemo1())) {
				sWhere1.append(" and p.create_time between to_date('"+sum.getStartTime()+"','yyyy-MM-dd HH24:mi:ss') and to_date('"+sum.getEndTime()+"','yyyy-MM-dd HH24:mi:ss') ");
			}

			if(sum.getMemo2()!=null&&!"".equals(sum.getMemo2())){
				sWhere3.append(" and t1.diameter_out>="+sum.getMemo2());
			}
			if(sum.getMemo3()!=null&&!"".equals(sum.getMemo3())){
				sWhere3.append(" and t1.diameter_out<="+sum.getMemo3());
			}
			if(sum.getMemo4()!=null&&!"".equals(sum.getMemo4().trim())){
				sWhere3.append(" and t1.cl_plan_no like '%"+sum.getMemo4().trim()+"%'");
			}

			PlnCuttolengthDsnMain pdm=(sum.getObject()==null?(new PlnCuttolengthDsnMain()):sum.getObject());
			if(sum.getObject()!=null){
				//条件2
				if(sum.getObject().getOrder_no()!=null
						&&!"".equals(sum.getObject().getOrder_no().trim())){
					sWhere2.append(" and p.order_no like '%"+sum.getObject().getOrder_no().trim()+"%' ");
				}
				if(sum.getObject().getProd_order_no()!=null
						&&!"".equals(sum.getObject().getProd_order_no().trim())){
					sWhere2.append(" and p.prod_order_no like '%"+sum.getObject().getProd_order_no().trim()+"%' ");
				}
				
				// 增加状态筛选框默认不显示已完成的计划
				if(Utils.isEmpty(sum.getObject().getStatus())) {
					sWhere0.append(" and t6.status != '5BCL10' ");
				} else if (!sum.getObject().getStatus().equals("0")) {
					sWhere0.append(" and t6.status = '"+sum.getObject().getStatus()+"'");
				}
			}
			List<PlnCuttolengthDsnMainSum> listPSum = this.getMapper(PlnCuttolengthDsnMainMapper.class)
					.doQueryCompletePlan(sWhere0.toString(),sWhere1.toString(), sWhere2.toString(), sWhere3.toString(),pdm);
			for(PlnCuttolengthDsnMainSum orders:listPSum){
				// 在界面查询刷新后，赋值 V_PlanNo 和 V_PlanSeq_Old
				v_planno_old.put(orders.getCl_plan_no(), orders.getPlan_seq());
				//加工计划备注PlnProcessPlan
//				PlnProcessPlan pplan=new PlnProcessPlan();
//				pplan.setOrder_no(orders.getOrder_no());
//				pplan.setCut_order_no(1L);
//				// SELECT PLAN_NO,PRODUCE_NO,CUT_ORDER_NO,ORDER_NO,PURCHASE_CONTRACT_NO,STEEL_CODE,STEEL_NAME,SPEC,MAT_WIDTH,MAT_THICK,MAT_LENGTH,MAT_DIAMETER_INN,MAT_DIAMETER_OUT,MAT_ESTIMATE_WEIGHT,WIDTH,THICK,LENGTH,DIAMETER_INN,DIAMETER_OUT,ESTIMATE_WEIGHT,CUT_STYLE,CROSSCUT_STYLE,CUT_TYPE,CUT_NUM,REMARK,VALID_FLAG,CREATE_MAN_NAME,CREATE_TIME,UPDATE_MAN_NAME,UPDATE_TIME FROM PLN_PROCESS_PLAN WHERE CUT_ORDER_NO = 1 AND ORDER_NO = 'YTGD-0329010001'
//				List<PlnProcessPlan> planList=this.getMapper(PlnProcessPlanMapper.class).findWithCondition(pplan, "", null, 0, 0);
//				if(planList.size()>0){
//					//关联加工计划信息表SLM_PROCESS_PLAN查询加工计划备注
//					orders.setProcessMemo(planList.get(0).getRemark());
//				}
			}
			rm.setData(listPSum);
			rm.setState("200");

		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询出错！");
			rm.setErrorInfo(ex.getMessage());
		}
		return rm;
	}

	/**
	 * 动作处理_移动确认按钮
	 * 
	 * @param sum V_PlanNo--按顺序保存左表计划号 查询的时候保存 V_PlanSeq_Old--按顺序保存左表计划顺序号
	 *            V_PlanSeq_New
	 * @return
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doMove(CommonPage<PlnCuttolengthPlan> sum) throws Exception{
		ResultModel rm = new ResultModel();
		// 记录计划号index用于查找对应循序号
		Integer i = 0;
		List<PlnCuttolengthPlan> plns = sum.getObjectList();
		List<String> tmp = new ArrayList<String>();
		PlnCuttolengthPlan p = new PlnCuttolengthPlan();
		for (PlnCuttolengthPlan pln : plns) {
			if(!tmp.contains(pln.getCl_plan_no())) {
				tmp.add(pln.getCl_plan_no());
			}else {
				continue;
			}
			i = v_planno_old.get(pln.getCl_plan_no());
			if (i == 0) {
				throw new Exception("调整计划顺序失败。计划[" + pln.getCl_plan_no() + "]的顺序或状态已经改变，请刷新重试。");
			}
			p.setCl_plan_no(pln.getCl_plan_no());
			;
			List<PlnCuttolengthPlan> plrp = this.getMapper(PlnCuttolengthPlanMapper.class).find(p, 0, 0);
			if (plrp == null || plrp.size() == 0) {
				throw new Exception("计划信息[" + pln.getCl_plan_no() + "]不存在！");
			}
//			if (!"0PCL01".equals(plrp.get(0).getStatus())) {
//				throw new Exception("只有已编制待下发计划允许调整循序！");
//			}
			int count = this.getMapper(PlnCuttolengthPlanMapper.class).doUpdateSeq(pln, i);
			if (count == 0) {
				throw new Exception("调整计划顺序失败。计划[" + pln.getCl_plan_no() + "]的顺序或状态已经改变，请刷新重试。");
			}
		}
		// 释放旧数据
		v_planno_old.clear();
		rm.setState("200");
		rm.setMsgInfo("调整计划循序成功!");
		return rm ; 
	}

	/**
	 * 横剪计划编制 虚拟物料号数组
	 * memo1 计划横剪时间
	 * memo2 机台编号
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doAddWeb(CommonPage<String[]> oci) throws Exception{
		ResultModel rm=new ResultModel();
		int i = 0;

		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		//虚拟物料号数组
		String[] ObjectNoVts=oci.getObject();
		List<PlnMaterielDetail> lpmd=new ArrayList<PlnMaterielDetail>();
		for(String s:ObjectNoVts){
			//查询虚拟卷
			PlnMaterielDetail pmd=new PlnMaterielDetail();
			pmd.setObject_no_vt(s);
			List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).find(pmd, 0, 0);

			if(lpmdq==null||lpmdq.size()==0){
				rm.setState("500");
				rm.setMsgInfo("虚拟物料["+s+"]信息不存在!");
				return rm;
			}
			if (Utils.isNotEmpty(lpmdq.get(0).getObject_no())) {
				YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).findById(lpmdq.get(0).getObject_no());
				if (Utils.isNotEmpty(ypd) && !"0".equals(ypd.getState())) {
					rm.setState("500");
					rm.setMsgInfo("请先将物料[" + lpmdq.get(0).getObject_no() + "]入库再编制计划！");
					return rm;
				}
			}
			
			//实际上只有一条
			for(PlnMaterielDetail pmdq:lpmdq){
				if(!"".equals(pmdq.getCl_plan_no())&&pmdq.getCl_plan_no()!=null){
					rm.setState("500");
					rm.setMsgInfo("虚拟物料["+s+"]已经在计划["+pmdq.getCl_plan_no()+"]内，无法再次编制！");
					return rm;
				}

				PlnCuttolengthPlanDetail ppd=new PlnCuttolengthPlanDetail();
				ppd.setObject_no_vt(pmdq.getObject_no_vt());
				int icount=this.getMapper(PlnCuttolengthPlanDetailMapper.class).countWithCondition(ppd," STATUS<= '0PCL10' ");
				if(icount>0){
					rm.setState("500");
					rm.setMsgInfo("虚拟物料["+s+"]已经在计划["+pmdq.getCl_plan_no()+"]内，无法再次编制！");
					return rm;
				}

				//若虚拟物料表的 (OPT_TIMES >=1 AND NEED_EXTOPT =0) ,则报错退出
				if(pmdq.getOpt_times()!=null&&pmdq.getOpt_times()>=1
						&&"1".equals(pmdq.getNeed_extopt())){
					rm.setState("500");
					rm.setMsgInfo("虚拟物料["+s+"]已经生产完毕，不能编制计划！");
					return rm;
				}

				//单重求和
				if(pmdq.getSingle_weight()==null){
					rm.setState("500");
					rm.setMsgInfo("虚拟物料["+s+"]没有单重！");
					return rm;
				}
				lpmd.add(pmdq);
			}
		}

		//保存相关数据: 
		String Dt=new SimpleDateFormat("yyMMdd").format(new Date());
		//横剪计划表：(CL+YYMMDD+3位流水)取当日流水最大值+1																				
		PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
		//倒叙找到最后一条数据
		List<PlnCuttolengthPlan> lpp=this.getMapper(PlnCuttolengthPlanMapper.class).findWithCondition(null, "", " serial_no desc ", 0, 1);
		if(lpp==null||lpp.size()==0){
			pp.setSerial_no(1l);
			pp.setCl_plan_no("CL"+Dt+String.format("%03d", 1));//CL180531001
		}else{
			pp.setSerial_no(lpp.get(0).getSerial_no()+1);
			if(Dt.equals(lpp.get(0).getCl_plan_no().substring(2,8))){
				pp.setCl_plan_no("CL"+Dt+String.format("%03d", Integer.parseInt(lpp.get(0).getCl_plan_no().substring(8,lpp.get(0).getCl_plan_no().length()))+1 ));
			}else{
				pp.setCl_plan_no("CL"+Dt+String.format("%03d", 1));
			}
		}
		pp.setPlan_seq(pp.getSerial_no());
		pp.setStatus("0PCL01");
		pp.setPline_code(lpmd.get(0).getPline_code());
		pp.setMachine_code(oci.getMemo2()==null?"M0003":oci.getMemo2());

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = sdf.parse(oci.getMemo1());
		pp.setStart_time(date);
		pp.setCreate_man_name(userName);
		pp.setCreate_time(new Date());
		this.getMapper(PlnCuttolengthPlanMapper.class).insert(pp);

		//横剪计划明细表：对选中的各母卷分别增加明细记录
		List<PlnCuttolengthPlanDetail> lppd=this.getMapper(PlnCuttolengthPlanDetailMapper.class).findWithCondition(null, "", " serial_no desc ", 0, 1);
		long sNo=0;
		if(lppd==null||lppd.size()==0){
			sNo=1;
		}else{
			sNo=lppd.get(0).getSerial_no()+1;
		}


		int isqe=0;
		PlnCuttolengthPlanDetail plpdq=new PlnCuttolengthPlanDetail();
		plpdq.setCl_plan_no(pp.getCl_plan_no());
		lppd=this.getMapper(PlnCuttolengthPlanDetailMapper.class).findWithCondition(plpdq, "", " cl_seq desc ", 0, 1);
		if(lppd==null||lppd.size()==0){
			isqe=1;
		}else{
			isqe=(int) (lppd.get(0).getCl_seq()+1);
		}

		//double dSum=0; 
		for(PlnMaterielDetail pmd:lpmd){
			PlnCuttolengthPlanDetail plpd=new PlnCuttolengthPlanDetail();
			plpd.setSerial_no(sNo++);
			plpd.setCl_plan_no(pp.getCl_plan_no().substring(0, 8)+String.format("%03d", Integer.parseInt(pp.getCl_plan_no().substring(8))+i));
			i++;
			plpd.setCl_seq(isqe++);
			plpd.setObject_no(pmd.getObject_no());
			plpd.setObject_no_vt(pmd.getObject_no_vt());
			plpd.setCl_design_no(pmd.getCl_design_no());
			plpd.setStatus("5BCL01");
			plpd.setPline_code(pmd.getPline_code());
			plpd.setMachine_code(oci.getMemo2()==null?"M0003":oci.getMemo2());
			plpd.setSteel_code(pmd.getSteel_code());
			plpd.setMat_width(pmd.getWidth());
			plpd.setMat_thick(pmd.getThick());
			plpd.setMat_diameter_inn(pmd.getDiameter_inn());
			plpd.setMat_diameter_out(pmd.getDiameter_out());
			plpd.setMat_length(pmd.getLength());
			plpd.setMat_single_weight(pmd.getSingle_weight());
			plpd.setPlan_opt_time(pp.getStart_time());
			plpd.setCreate_man_name(userName);
			plpd.setCreate_time(new Date());

			PlnCuttolengthDsnMain pldm=new PlnCuttolengthDsnMain();
			pldm.setCl_design_no(pmd.getCl_design_no());
			List<PlnCuttolengthDsnMain> lpldm=this.getMapper(PlnCuttolengthDsnMainMapper.class).find(pldm, 0, 1);
			plpd.setRate(lpldm.get(0).getProd_rate());
			//---------SUB_COUNT	子卷数	根据横剪设计号
			plpd.setSub_count(lpldm.get(0).getSub_count().intValue());
			this.getMapper(PlnCuttolengthPlanDetailMapper.class).insert(plpd);

			//dSum+=plpd.getMat_single_weight();
			//虚拟物料表--修改各母卷，及其对应子堆垛 的  横剪计划号[CL_PLANNO]字段 
			PlnMaterielDetail pmdu=new PlnMaterielDetail();
			pmdu.setCl_plan_no(plpd.getCl_plan_no());
			pmdu.setSerial_no(pmd.getSerial_no());
			this.getMapper(PlnMaterielDetailMapper.class).update(pmdu);
			//写虚拟物料履历，状态填:0PCL01		子卷																			
			this.getBean(MesApiServiceImpl.class).InsertMatVtProc(pmd.getObject_no_vt(), "0PCL01", userName, new Date());
		}
		//虚拟物料表：修改各母卷，的横剪计划号[Cl_plan_no]字段
		for(String s:ObjectNoVts){
			PlnMaterielDetail pmdu=new PlnMaterielDetail();
			pmdu.setObject_no_vt(s);
			pmdu.setCl_plan_no(pp.getCl_plan_no());
			this.getMapper(PlnMaterielDetailMapper.class).doUpdateClPlanNo(pmdu);
			//写虚拟物料履历，状态填:0PCL01	母卷																		
			this.getBean(MesApiServiceImpl.class).InsertMatVtProc(s, "0PCL01", userName, new Date());
			doAddChildMethod(pmdu);
		}
		rm.setState("200");
		return rm;
	}

	/**
	 * doAddWeb的子方法
	 * @throws Exception 
	 * */
	private void doAddChildMethod(PlnMaterielDetail pmd) throws Exception{
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		//判断虚拟母卷对应的实物号是否挂料,如果  object_no<>null

		pmd=this.getMapper(PlnMaterielDetailMapper.class).find(pmd, 0, 1).get(0);

		if(pmd.getObject_no()!=null){
			//调用接口 新增实物物料状态跟踪	
			//调用 新增实物物料状态跟踪:  传入（实物子卷号,5BCL10，操作时间，操作人，""）
			PrcMaterielProcess pmp=new PrcMaterielProcess();
			pmp.setObject_no(pmd.getObject_no());
			pmp.setPrc_code("5BCL01");//新增的状态
			pmp.setCreate_time(new Date());
			pmp.setCreate_man_name(userName);
			pmp.setRemark("");
			//新增物料跟踪：
			this.getBean(MesApiServiceImpl.class).INSERT_OBJ_PROCESS(pmp);
		}
		double One_Weight=0;
		int One_Quantity=0;
		//根据母卷的CL_DESIGN_NO , 读取【pln_dsn_order_info】
		PlnDsnOrderInfo pdoi = new PlnDsnOrderInfo();
		pdoi.setDesign_no(pmd.getCl_design_no());
		List<PlnDsnOrderInfo> lpoi=this.getMapper(PlnDsnOrderInfoMapper.class).find(pdoi, 0, 0);
		if(lpoi!=null&&lpoi.size()>0){
			for(PlnDsnOrderInfo s2:lpoi){
				One_Weight+=(s2.getWeight_in_one()== null ? 0:s2.getWeight_in_one());
				One_Quantity+=(s2.getQuantity_in_one()== null ? 0:s2.getQuantity_in_one());

				//根据S2的 生产订单号，修改对应 生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps=new PlnProdorderStatistic();
				pps.setProd_order_no(s2.getProd_order_no());
				pps.setCl_planed(s2.getWeight_in_one());
				pps.setCl_planed_cnt(s2.getQuantity_in_one());
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

				//根据S2的 订单号，修改  订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos=new PlnOrderStatistic();
				pos.setOrder_no(s2.getOrder_no());
				pos.setCl_planed(s2.getWeight_in_one());
				pos.setCl_planed_cnt(s2.getQuantity_in_one());
				this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
			}
		}
		//		在 横剪计划进程表 [PLN_CL_PLAN_STATISTIC]， 没横剪计划号记录，就创建一条主记录
		PlnClPlanStatistic plps=new PlnClPlanStatistic();
		plps.setCl_plan_no(pmd.getCl_plan_no());
		int icount=this.getMapper(PlnClPlanStatisticMapper.class).count(plps);
		if(icount==0){
			List<PlnClPlanStatistic> lplps=this.getMapper(PlnClPlanStatisticMapper.class).findWithCondition(null, null, " to_number(serial_no) desc ", 0, 1);
			if(lplps!=null&&lplps.size()>0){
				plps.setSerial_no((Long.parseLong(lplps.get(0).getSerial_no().trim())+1)+"");
			}else{
				plps.setSerial_no("1");
			}
		}
		//修改 横剪计划进程表 [PLN_CL_PLAN_STATISTIC] 
		plps.setMat_planed(pmd.getSingle_weight());
		plps.setMat_planed_cnt(1);
		plps.setPlaned(One_Weight);
		plps.setPlaned_cnt(One_Quantity);
		if(icount==0){
			this.getMapper(PlnClPlanStatisticMapper.class).insert(plps);
		}else{
			this.getMapper(PlnClPlanStatisticMapper.class).doUpdatePlaned(plps);
		}
		//修改横剪计划表： QUANTITY 数量 += 1;   TOTACLEIGHT 总重量 += 虚拟物料号单重
		PlnCuttolengthPlan plp=new PlnCuttolengthPlan();
		plp.setCl_plan_no(pmd.getCl_plan_no());
		plp.setMat_quantity(1);
		plp.setMat_weight(pmd.getSingle_weight());
		this.getMapper(PlnCuttolengthPlanMapper.class).doUpdatePlaned(plp);

		//调用【接口文档--公共函数SHEET--修改横剪计划主表状态
		this.getBean(MesApiCrCrossCuttingMServiceImpl.class).doUpdatePlnCuttolengthPlan(pmd.getCl_plan_no());
	}

	/**
	 * 选定物料加入横剪计划
	 * 传入PlnMaterielDetail object_vt_no 数组Cl_plan_no数组
	 * memo1 计划开平时间
	 * memo2 机台编号
	 * memo3 = 1 :母卷批量编制到同一个计划 ; 默认为空:一个卷一个计划。
	 * memo4 = 1  捆包计划
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doCheckPlanAdd(CommonPage<PlnMaterielDetail> oci) throws Exception{
		ResultModel rm=new ResultModel();
		if (Utils.isEmpty(oci.getMemo2())) {
			oci.setMemo2("M0003");
		}
		// 获取主计划号和序列号
		PlnCuttolengthPlan ppoo = getPlanNo();
		PlnCuttolengthPlan plpl = new PlnCuttolengthPlan();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		String Cl_plan_no = null;
		List<PlnMaterielDetail> lpmd=oci.getObjectList();
		// 循环处理传入的物料和计划号数组
		for (PlnMaterielDetail plnmd : lpmd) {
			// 判断是否传入计划号
			if (plnmd.getCl_plan_no()!=null && !"".equals(plnmd.getCl_plan_no())) {
				plpl.setCl_plan_no(plnmd.getCl_plan_no());
				plpl.setPlan_seq(plnmd.getPlan_seq());
				List<PlnCuttolengthPlan> lplp=this.getMapper(PlnCuttolengthPlanMapper.class).find(plpl, 0, 1);
				if(lplp==null||lplp.size()==0){
					rm.setState("500");
					rm.setMsgInfo("开平计划["+plnmd.getCl_plan_no()+"]信息不存在!");
					return rm;
				}
				if(lplp.get(0).getStatus().trim().compareTo("0PCL01")>0){
					rm.setState("500");
					rm.setMsgInfo("开平计划["+plnmd.getCl_plan_no()+"]已下发，不能加入!");
					return rm;
				}
				// 捆包计划
				if(lplp.get(0).getIs_bales()==1) {
					rm.setState("500");
					rm.setMsgInfo("所选计划["+plnmd.getCl_plan_no()+"]为捆包计划不能加入!");
					return rm;
				}
				// 判断虚拟物料信息
				ResultModel rmValid = doPlanJudgeByObject_no_vt(plnmd.getObject_no_vt());
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
				Cl_plan_no = plnmd.getCl_plan_no();
				// 新增开平计划明细表记录
				doAddDetail(plnmd, userName, oci.getMemo2()==null?"M0003":oci.getMemo2(),oci.getMemo6());
			}else {
				// 判断虚拟物料信息
				ResultModel rmValid = doPlanJudgeByObject_no_vt(plnmd.getObject_no_vt());
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
				if ("1".equals(oci.getMemo3())) {
					PlnCuttolengthPlan pp = ppoo;
					Cl_plan_no = pp.getCl_plan_no();
					List<PlnCuttolengthPlan> plnleng = this.getMapper(PlnCuttolengthPlanMapper.class)
							.findWithCondition(null, "cl_plan_no = '"+Cl_plan_no+"'", "", 0, 1);
					if (plnleng == null || plnleng.size()==0) {
						pp.setPlan_seq(pp.getSerial_no());
						pp.setStatus("0PCL01");
						pp.setPline_code(lpmd.get(0).getPline_code());
						pp.setMachine_code(oci.getMemo2());
						
						// 捆包计划
						if("1".equals(oci.getMemo4())) {
							pp.setIs_bales(1);
						}
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
						Date date = sdf.parse(oci.getMemo1());
						pp.setStart_time(date);
						pp.setCreate_man_name(userName);
						pp.setCreate_time(new Date());
						this.getMapper(PlnCuttolengthPlanMapper.class).insert(pp);
					}
					// 新增开平计划明细表记录
					PlnMaterielDetail plnmh = new PlnMaterielDetail();
					plnmh.setCl_plan_no(pp.getCl_plan_no());
					plnmh.setObject_no_vt(plnmd.getObject_no_vt());
					doAddDetail(plnmh, userName, oci.getMemo2()==null?"M0003":oci.getMemo2(),oci.getMemo6());

				} else {
					// 新增开平计划主记录
					PlnCuttolengthPlan pp = getPlanNo();
					Cl_plan_no = pp.getCl_plan_no();
					pp.setPlan_seq(pp.getSerial_no());
					pp.setStatus("0PCL01");
					pp.setPline_code(lpmd.get(0).getPline_code());
					pp.setMachine_code(oci.getMemo2());

					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					Date date = sdf.parse(oci.getMemo1());
					pp.setStart_time(date);
					pp.setCreate_man_name(userName);
					pp.setCreate_time(new Date());
					this.getMapper(PlnCuttolengthPlanMapper.class).insert(pp);

					// 新增开平计划明细表
					PlnMaterielDetail plnmh = new PlnMaterielDetail();
					plnmh.setCl_plan_no(pp.getCl_plan_no());
					plnmh.setObject_no_vt(plnmd.getObject_no_vt());
					doAddDetail(plnmh, userName,oci.getMemo2()==null?"M0003":oci.getMemo2(),oci.getMemo6());
				}
			}
			// 修改其他信息
			PlnMaterielDetail pmdu=new PlnMaterielDetail();
			pmdu.setObject_no_vt(plnmd.getObject_no_vt());
			pmdu.setCl_plan_no(Cl_plan_no);
			doAddChildMethod(pmdu);

			//写虚拟物料履历，状态填:0PCL01 母卷																		
			this.getBean(MesApiServiceImpl.class).InsertMatVtProc(plnmd.getObject_no_vt(), "0PCL01", userName, new Date());

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


	/**
	 * 横剪计划取消
	 * 传入 横剪计划号数组
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doCancelPlanWeb(CommonPage<PlnCuttolengthPlan> 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<PlnCuttolengthPlan> sclPlanNo=oci.getObjectList();
		List<String> plan_no = new ArrayList<String>();
		for(PlnCuttolengthPlan pc:sclPlanNo){
			//循环处理对应计划中 横剪明细（母卷）相关数据
			PlnCuttolengthPlanDetail plpd=new PlnCuttolengthPlanDetail();
			plpd.setCl_plan_no(pc.getCl_plan_no());
			
			// 去重
			if(plan_no.contains(plpd.getCl_plan_no())) {
				continue ;
			}else {
				plan_no.add(plpd.getCl_plan_no());
			}
		
			List<PlnCuttolengthPlanDetail> lplpd=this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(plpd, 0, 0);
			rm = doCheckCancelPlanChild(lplpd);
			if(!"200".equals(rm.getState())){
				throw new Exception(rm.getMsgInfo());
			}
			for (PlnCuttolengthPlanDetail ppd : lplpd) {
				MesOprLog mol = new MesOprLog("生产管理", "开平计划编制", "取消计划", userName, opr_time, ppd.getObject_no(), null, null, null, null);
				this.getMapper(MesOprLogMapper.class).insert(mol);
			}
		}
		return rm;
	}

	/**
	 * 传入 横剪计划号、虚拟母卷号
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doCheckCancelPlanWeb(CommonPage<PlnCuttolengthPlanDetail> oci) throws Exception {
		List<PlnCuttolengthPlanDetail> lplpd=oci.getObjectList();
		ResultModel rm=doCheckCancelPlanChild(lplpd);
		return rm;
	}

	/**
	 * 选定物料移除计划
	 * @throws Exception 
	 * */
	public ResultModel doCheckCancelPlanChild(List<PlnCuttolengthPlanDetail> lplpd) throws Exception{
		ResultModel rm=new ResultModel();

		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		List<PlnCuttolengthPlanDetail> lp=new ArrayList<PlnCuttolengthPlanDetail>();
		for(PlnCuttolengthPlanDetail plpd:lplpd){
			PlnCuttolengthPlanDetail pq=new PlnCuttolengthPlanDetail();
			pq.setCl_plan_no(plpd.getCl_plan_no());
			pq.setObject_no_vt(plpd.getObject_no_vt());
			List<PlnCuttolengthPlanDetail> lpq=this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(pq, 0, 1);
			if(lpq==null||lpq.size()==0){
				rm.setState("500");
				rm.setMsgInfo("虚拟母卷["+plpd.getObject_no_vt()+"]的横剪计划["+plpd.getCl_plan_no()+"]不存在，无法删除！");
				return rm;
			}
			//状态STATUS>5BCL01, 如果成立，则报错退出
			if("5BCL01".compareTo(lpq.get(0).getStatus())<0){
				rm.setState("500");
				rm.setMsgInfo("母卷["+lpq.get(0).getObject_no_vt()+"]的横剪计划已下发，无法删除！");
				return rm;
			}
			// 如果是捆包计划将子卷删除并且将无效子卷恢复
			if(Utils.isNotEmpty(lpq.get(0).getIs_bales()) && lpq.get(0).getIs_bales() == 1 ) {
				// 主计划将虚拟子卷删除
				if(Utils.isNotEmpty(lpq.get(0).getIs_main_plan()) &&  lpq.get(0).getIs_main_plan()== 1) {
					this.getMapper(PlnMaterielDetailMapper.class).delByMat(lpq.get(0).getObject_no_vt());
					this.getMapper(PlnMaterielDetailMapper.class).updateMainMat(lpq.get(0).getObject_no_vt());
				}
				// 将虚拟子卷恢复
				this.getMapper(PlnMaterielDetailMapper.class).MatToValid(lpq.get(0).getObject_no_vt());
			}
			lp.add(lpq.get(0));
		}

		for(PlnCuttolengthPlanDetail p:lp){
			//写虚拟物料履历，状态填:0PCLXX		母卷																			
			this.getBean(MesApiServiceImpl.class).InsertMatVtProc(p.getObject_no_vt(), "0PCLXX", userName, new Date());
			
			// 查询子卷
			List<PlnMaterielDetail> listchild = this.getMapper(
					PlnMaterielDetailMapper.class).findWithCondition(null,
					" mat_object_no_vt = '" + p.getObject_no_vt() + "'", null,
					0, 0);
			if (Utils.isNotEmpty(listchild)) {
				for (PlnMaterielDetail pln : listchild) {
					// 写虚拟物料履历，状态填:0PCL01 子卷
					this.getBean(MesApiServiceImpl.class).InsertMatVtProc(
							pln.getObject_no_vt(), "0PCLXX", userName,
							new Date());
				}
			}

			//修改虚拟物料表 修改各母卷 的 横剪计划号[CL_PLANNO]字段为空。																				
			PlnMaterielDetail pmdu=new PlnMaterielDetail();
			pmdu.setObject_no_vt(p.getObject_no_vt());
			pmdu.setCl_plan_no(null);
			pmdu.setStatus("0PDB10");
			this.getMapper(PlnMaterielDetailMapper.class).doUpdateClPlanNo(pmdu);
			
			// 修改虚拟物料子卷开平计划号
			PlnMaterielDetail child =new PlnMaterielDetail();
			child.setCl_plan_no(null);
			child.setMat_object_no_vt(p.getObject_no_vt());
			child.setStatus("0PDB10");
			// child.setMachine_code("");
			this.getMapper(PlnMaterielDetailMapper.class).updateClByMat_No(child);

			if(p.getObject_no()!=null){
				//调用生产计划模块物料跟踪撤销接口
				PrcMaterielProcess pmp=new PrcMaterielProcess();
				pmp.setObject_no(p.getObject_no());
				pmp.setPrc_code("5BCL01");//新增的状态
				pmp.setRemark("计划已编制撤销");
				//撤销实物物料状态跟踪函数:
				String tmp=this.getBean(MesApiServiceImpl.class).ARRAYLIST(pmp).getState();

			}
			
			//删除横剪计划明细相关母卷数据
			this.getMapper(PlnCuttolengthPlanDetailMapper.class).doDelete(p);
			//========================================================================	


			//根据虚拟母卷的【CL_DESIGN_NO】, 读取【pln_dsn_order_info】中的所有数据(DESIGN_NO= 母卷CREATE_DESIGN_NO)
			PlnMaterielDetail pmdc=new PlnMaterielDetail();
			pmdc.setObject_no_vt(p.getObject_no_vt());
			List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmdc, 0, 0);

			//准备临时变量:  One_Weight=0;   One_Quantity=0;
			double One_Weight=0;
			int One_Quantity=0;

			PlnDsnOrderInfo pdoi=new PlnDsnOrderInfo();
			pdoi.setDesign_no(lpmd.get(0).getCreate_design_no());
			List<PlnDsnOrderInfo> lpdoi=this.getMapper(PlnDsnOrderInfoMapper.class).find(pdoi, 0, 0);
			for(PlnDsnOrderInfo s2:lpdoi){
				//One_Weight+=S2.WEIGHT_IN_ONE;   One_Quantity+=S2.QUANTITY_IN_ONE;
				One_Weight+=s2.getWeight_in_one() == null ? 0 : s2.getWeight_in_one();
				One_Quantity+=s2.getQuantity_in_one();
				//根据S2的 生产订单号，修改对应 生产订单进程表
				PlnProdorderStatistic pps=new PlnProdorderStatistic();
				pps.setProd_order_no(s2.getProd_order_no());
				pps.setCl_planed(s2.getWeight_in_one()==null?0:(-s2.getWeight_in_one()));
				pps.setCl_planed_cnt(s2.getQuantity_in_one()==null?0:(-s2.getQuantity_in_one()));
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

				//根据S2的 订单号，修改  订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos=new PlnOrderStatistic();
				pos.setOrder_no(s2.getOrder_no());
				pos.setCl_planed(s2.getWeight_in_one()==null?0:(-s2.getWeight_in_one()));
				pos.setCl_planed_cnt(s2.getQuantity_in_one()==null?0:(-s2.getQuantity_in_one()));
				this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
			}

			// 查找横剪计划明细表【PLN_CUTTOLENGTH_PLAN_DETAIL】  where CL_plan_no=【母卷对应 横剪计划号】的记录条数。 
			PlnCuttolengthPlanDetail plpd=new PlnCuttolengthPlanDetail();
			plpd.setCl_plan_no(p.getCl_plan_no());
			List<PlnCuttolengthPlanDetail> lplpdq=this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(plpd, 0, 0);


			if(lplpdq==null||lplpdq.size()==0){//如果 记录数=0，
				//删除 横剪计划进程表相关横剪计划记录 [PLN_ORDER_STATISTIC]
				PlnClPlanStatistic pps=new PlnClPlanStatistic();
				pps.setCl_plan_no(p.getCl_plan_no());
				this.getMapper(PlnClPlanStatisticMapper.class).doDelete(pps);

				//删除横剪计划主表数据
				PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
				pp.setCl_plan_no(p.getCl_plan_no());
				this.getMapper(PlnCuttolengthPlanMapper.class).doDeleteClPlanNo(pp);
			}else{
				//修改对应横剪计划主表【PLN_Cuttolength_PLAN】
				PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
				pp.setCl_plan_no(p.getCl_plan_no());
				pp.setMat_quantity(-1);
				pp.setMat_weight(lpmd.get(0).getSingle_weight()==null?null:(-lpmd.get(0).getSingle_weight()));
				this.getMapper(PlnCuttolengthPlanMapper.class).doUpdatePlaned(pp);

				//修改横剪计划号记录 [PLN_CL_PLAN_STATISTIC]，填写字段
				PlnClPlanStatistic pps=new PlnClPlanStatistic();
				pps.setMat_planed(lpmd.get(0).getSingle_weight()==null?0:(-lpmd.get(0).getSingle_weight()));
				pps.setMat_planed_cnt(-1);
				pps.setPlaned(-One_Weight);
				pps.setPlaned_cnt(-One_Quantity);
				pps.setCl_plan_no(p.getCl_plan_no());
				this.getMapper(PlnClPlanStatisticMapper.class).doUpdatePlaned(pps);

				//调用【接口文档--公共函数SHEET--修改横剪计划主表状态
				this.getBean(MesApiCrCrossCuttingMServiceImpl.class).doUpdatePlnCuttolengthPlan(p.getCl_plan_no());

			}	
		}
		rm.setState("200");
		return rm;
	}
	
	/**
	 * 选定物料移除计划(质量自动脱单调用)
	 * @throws Exception 
	 * */
	public ResultModel doCancelPlanAuto(List<PlnCuttolengthPlanDetail> lplpd,String userName) throws Exception{
		
		ResultModel rm=new ResultModel();
		List<PlnCuttolengthPlanDetail> lp=new ArrayList<PlnCuttolengthPlanDetail>();
		for(PlnCuttolengthPlanDetail plpd:lplpd){
			PlnCuttolengthPlanDetail pq=new PlnCuttolengthPlanDetail();
			pq.setCl_plan_no(plpd.getCl_plan_no());
			pq.setObject_no_vt(plpd.getObject_no_vt());
			List<PlnCuttolengthPlanDetail> lpq=this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(pq, 0, 1);
			if(lpq==null||lpq.size()==0){
				rm.setState("500");
				rm.setMsgInfo("虚拟母卷["+plpd.getObject_no_vt()+"]的横剪计划["+plpd.getCl_plan_no()+"]不存在，无法删除！");
				return rm;
			}
			//状态STATUS>5BCL01, 如果成立，则报错退出
			if("5BCL01".compareTo(lpq.get(0).getStatus())<0){
				rm.setState("500");
				rm.setMsgInfo("母卷["+lpq.get(0).getObject_no_vt()+"]的横剪计划已下发，无法删除！");
				return rm;
			}
			lp.add(lpq.get(0));
		}
		
		for(PlnCuttolengthPlanDetail p:lp){
			//写虚拟物料履历，状态填:0PCLXX		母卷																			
			this.getService(MesApiService.class).InsertMatVtProc(p.getObject_no_vt(), "0PCLXX", userName, new Date());
			
			// 查询子卷
			List<PlnMaterielDetail> listchild = this.getMapper(
					PlnMaterielDetailMapper.class).findWithCondition(null,
							" mat_object_no_vt = '" + p.getObject_no_vt() + "'", null,
							0, 0);
			if (Utils.isNotEmpty(listchild)) {
				for (PlnMaterielDetail pln : listchild) {
					// 写虚拟物料履历，状态填:0PCL01 子卷
					this.getService(MesApiService.class).InsertMatVtProc(
							pln.getObject_no_vt(), "0PCLXX", userName,
							new Date());
				}
			}
			
			//修改虚拟物料表 修改各母卷 的 横剪计划号[CL_PLANNO]字段为空。																				
			PlnMaterielDetail pmdu=new PlnMaterielDetail();
			pmdu.setObject_no_vt(p.getObject_no_vt());
			pmdu.setCl_plan_no(null);
			pmdu.setStatus("0PDB10");
			this.getMapper(PlnMaterielDetailMapper.class).doUpdateClPlanNo(pmdu);
			
			// 修改虚拟物料子卷开平计划号
			PlnMaterielDetail child =new PlnMaterielDetail();
			child.setCl_plan_no(null);
			child.setMat_object_no_vt(p.getObject_no_vt());
			child.setStatus("0PDB10");
			// child.setMachine_code("");
			this.getMapper(PlnMaterielDetailMapper.class).updateClByMat_No(child);
			
			if(p.getObject_no()!=null){
				//调用生产计划模块物料跟踪撤销接口
				PrcMaterielProcess pmp=new PrcMaterielProcess();
				pmp.setObject_no(p.getObject_no());
				pmp.setPrc_code("5BCL01");//新增的状态
				pmp.setRemark("计划已编制撤销");
				//撤销实物物料状态跟踪函数:
				String tmp=this.getService(MesApiService.class).ARRAYLIST(pmp).getState();
				
			}
			
			//删除横剪计划明细相关母卷数据
			this.getMapper(PlnCuttolengthPlanDetailMapper.class).doDelete(p);
			//========================================================================	
			
			
			//根据虚拟母卷的【CL_DESIGN_NO】, 读取【pln_dsn_order_info】中的所有数据(DESIGN_NO= 母卷CREATE_DESIGN_NO)
			PlnMaterielDetail pmdc=new PlnMaterielDetail();
			pmdc.setObject_no_vt(p.getObject_no_vt());
			List<PlnMaterielDetail> lpmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmdc, 0, 0);
			
			//准备临时变量:  One_Weight=0;   One_Quantity=0;
			double One_Weight=0;
			int One_Quantity=0;
			
			PlnDsnOrderInfo pdoi=new PlnDsnOrderInfo();
			pdoi.setDesign_no(lpmd.get(0).getCreate_design_no());
			List<PlnDsnOrderInfo> lpdoi=this.getMapper(PlnDsnOrderInfoMapper.class).find(pdoi, 0, 0);
			for(PlnDsnOrderInfo s2:lpdoi){
				//One_Weight+=S2.WEIGHT_IN_ONE;   One_Quantity+=S2.QUANTITY_IN_ONE;
				One_Weight+=s2.getWeight_in_one();
				One_Quantity+=s2.getQuantity_in_one();
				//根据S2的 生产订单号，修改对应 生产订单进程表
				PlnProdorderStatistic pps=new PlnProdorderStatistic();
				pps.setProd_order_no(s2.getProd_order_no());
				pps.setCl_planed(s2.getWeight_in_one()==null?0:(-s2.getWeight_in_one()));
				pps.setCl_planed_cnt(s2.getQuantity_in_one()==null?0:(-s2.getQuantity_in_one()));
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
				
				//根据S2的 订单号，修改  订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos=new PlnOrderStatistic();
				pos.setOrder_no(s2.getOrder_no());
				pos.setCl_planed(s2.getWeight_in_one()==null?0:(-s2.getWeight_in_one()));
				pos.setCl_planed_cnt(s2.getQuantity_in_one()==null?0:(-s2.getQuantity_in_one()));
				this.getMapper(PlnOrderStatisticMapper.class).doUpdateClPlaned(pos);
			}
			
			// 查找横剪计划明细表【PLN_CUTTOLENGTH_PLAN_DETAIL】  where CL_plan_no=【母卷对应 横剪计划号】的记录条数。 
			PlnCuttolengthPlanDetail plpd=new PlnCuttolengthPlanDetail();
			plpd.setCl_plan_no(p.getCl_plan_no());
			List<PlnCuttolengthPlanDetail> lplpdq=this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(plpd, 0, 0);
			
			
			if(lplpdq==null||lplpdq.size()==0){//如果 记录数=0，
				//删除 横剪计划进程表相关横剪计划记录 [PLN_ORDER_STATISTIC]
				PlnClPlanStatistic pps=new PlnClPlanStatistic();
				pps.setCl_plan_no(p.getCl_plan_no());
				this.getMapper(PlnClPlanStatisticMapper.class).doDelete(pps);
				
				//删除横剪计划主表数据
				PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
				pp.setCl_plan_no(p.getCl_plan_no());
				this.getMapper(PlnCuttolengthPlanMapper.class).doDeleteClPlanNo(pp);
			}else{
				//修改对应横剪计划主表【PLN_Cuttolength_PLAN】
				PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
				pp.setCl_plan_no(p.getCl_plan_no());
				pp.setMat_quantity(-1);
				pp.setMat_weight(lpmd.get(0).getSingle_weight()==null?null:(-lpmd.get(0).getSingle_weight()));
				this.getMapper(PlnCuttolengthPlanMapper.class).doUpdatePlaned(pp);
				
				//修改横剪计划号记录 [PLN_CL_PLAN_STATISTIC]，填写字段
				PlnClPlanStatistic pps=new PlnClPlanStatistic();
				pps.setMat_planed(lpmd.get(0).getSingle_weight()==null?0:(-lpmd.get(0).getSingle_weight()));
				pps.setMat_planed_cnt(-1);
				pps.setPlaned(-One_Weight);
				pps.setPlaned_cnt(-One_Quantity);
				pps.setCl_plan_no(p.getCl_plan_no());
				this.getMapper(PlnClPlanStatisticMapper.class).doUpdatePlaned(pps);
				
				//调用【接口文档--公共函数SHEET--修改横剪计划主表状态
				this.getService(MesApiCrCrossCuttingMService.class).doUpdatePlnCuttolengthPlan(p.getCl_plan_no());
				
			}	
		}
		rm.setState("200");
		return rm;
	}


	/**
	 * 横剪计划下发 
	 * objectList
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doSendPlanWeb(CommonPage<PlnCuttolengthPlan> oci) throws Exception {
		ResultModel rm=new ResultModel();
		List<PlnCuttolengthPlan> lplp=oci.getObjectList();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		//去重操作
		List<PlnCuttolengthPlan> lplpC=new ArrayList<PlnCuttolengthPlan>();
		for(PlnCuttolengthPlan plp:lplp){
			if(lplpC.size()==0){
				lplpC.add(plp);
			}else{
				boolean flag=true;
				for(PlnCuttolengthPlan plpc:lplpC){
					if(plpc.getCl_plan_no().equals(plp.getCl_plan_no())){
						flag=false;
						break;
					}
				}
				//未重复
				if(flag){
					lplpC.add(plp);
				}
			}
		}


		for(PlnCuttolengthPlan pc:lplpC){
			
			// 判断物料是否在库
			this.getBean(MesApiDesignInfoImpl.class).JudgeIsOrNotZk(pc.getObject_no());
			
			PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
			pp.setCl_plan_no(pc.getCl_plan_no());
			List<PlnCuttolengthPlan> lp=this.getMapper(PlnCuttolengthPlanMapper.class).find(pp, 0, 0);
			if(lp==null||lp.size()==0){
				rm.setState("500");
				rm.setMsgInfo("横剪计划["+pc.getCl_plan_no()+"]信息不存在!");
				return rm;
			}
			if(!"0PCL01".equals(lp.get(0).getStatus())){
				rm.setState("500");
				rm.setMsgInfo("横剪计划["+pc.getCl_plan_no()+"]已下发，不能重复下发!");
				return rm;
			}
			//实际上包含了母卷跟子卷
			PlnCuttolengthPlanDetail plpd=new PlnCuttolengthPlanDetail();
			plpd.setCl_plan_no(pc.getCl_plan_no());
			pc.setChild(this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(plpd, 0, 0));
		}

		for(PlnCuttolengthPlan pc:lplpC){
			//修改横剪计划表： 相关计划的状态给为：0PCL02																					
			pc.setStatus("0PCL02");
			this.getMapper(PlnCuttolengthPlanMapper.class).doUpdate(pc);

			//修改横剪计划明细表：计划内的的各母卷分别修改状态为：0PCL02																					
			for(PlnCuttolengthPlanDetail pcc:pc.getChild()){
				pcc.setStatus("5BCL02");
				//修改横剪计划明细表：计划内的的各母卷分别修改状态为：5BCL02		
				// 增加下发时间下发人
				pcc.setSender(userName);
				pcc.setSend_date(new Date());
				this.getMapper(PlnCuttolengthPlanDetailMapper.class).doUpdateStatus(pcc);

				//虚拟物料表：修改母卷状态
				PlnMaterielDetail pmdu=new PlnMaterielDetail();
				pmdu.setCl_plan_no(pcc.getCl_plan_no());
				pmdu.setObject_no_vt(pcc.getObject_no_vt());
				List<PlnMaterielDetail> pmddd = this.getMapper(PlnMaterielDetailMapper.class).find(pmdu, 0, 1);
				
				List<PlnProdorder> ppoL = this.getMapper(PlnProdorderMapper.class).findWithCondition(null, " PROD_ORDER_NO='"+pmddd.get(0).getProd_order_no()+"'", null, 0, 0);
				if (ppoL == null || ppoL.size() <= 0) {
					throw new Exception("生产订单：" + ppoL.get(0).getOrder_no() + " 不存在");
				}
				// 验证生产订单状态是否为订单保留：
				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()+"]为 ‘订单作废’ 状态，不允许下发");
				}
				
				// 验证生产订单是否锁定
				boolean flag_l = this.getBean(MesApiDesignInfoImpl.class).pOrdIsLocked(pmddd.get(0).getProd_order_no());
				if (flag_l) {
					throw new Exception("生产订单已经锁定[订单变更中],不允许下发计划到车间!");
				}
				pmdu.setStatus("0PCL02");
				this.getMapper(PlnMaterielDetailMapper.class).doUpdateClPlanNo(pmdu);
				
				// 修改虚拟物料子卷状态
				PlnMaterielDetail child =new PlnMaterielDetail();
				child.setCl_plan_no(pcc.getCl_plan_no());
				child.setMat_object_no_vt(pcc.getObject_no_vt());
				child.setStatus("0PCL02");
				this.getMapper(PlnMaterielDetailMapper.class).updateClByMat_No(child);
				
				//写虚拟物料履历，状态填:0PCL02		母卷跟子卷信息																			
				this.getBean(MesApiServiceImpl.class).InsertMatVtProc(pcc.getObject_no_vt(), "0PCL02", userName, new Date());

				//2018-05-05新增实物跟踪 //调用生产计划模块物料跟踪接口 
				PrcMaterielProcess pmp=new PrcMaterielProcess();
				pmp.setPrc_code("5BCL02");//新增的状态
				pmp.setCreate_time(new Date());//来源.
				pmp.setObject_no(pcc.getObject_no());
				pmp.setCreate_man_name(userName);
				pmp.setRemark("计划已下发");
				//新增物料跟踪
				int tmp= this.getBean(MesApiServiceImpl.class).INSERT_OBJ_PROCESS(pmp);
//				if(tmp==-1){
//				throw new Exception("物料跟踪失败");
//				}
			}
		}

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

	/**
	 * 横剪计划取消下发
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doSendPlanCancelWeb(CommonPage<PlnCuttolengthPlan> oci) throws Exception {
		ResultModel rm=new ResultModel();
		List<PlnCuttolengthPlan> lplp=oci.getObjectList();

		// 去重操作
		List<PlnCuttolengthPlan> lplpC = new ArrayList<PlnCuttolengthPlan>();
		for (PlnCuttolengthPlan plp : lplp) {
			if (lplpC.size() == 0) {
				lplpC.add(plp);
			} else {
				boolean flag = true;
				for (PlnCuttolengthPlan plpc : lplpC) {
					if (plpc.getCl_plan_no().equals(plp.getCl_plan_no())) {
						flag = false;
						break;
					}
				}
				// 未重复
				if (flag) {
					lplpC.add(plp);
				}
			}
		}

		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);

		for(PlnCuttolengthPlan pc:lplpC){
			PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
			pp.setCl_plan_no(pc.getCl_plan_no());
			List<PlnCuttolengthPlan> lp=this.getMapper(PlnCuttolengthPlanMapper.class).find(pp, 0, 0);
			if(lp==null||lp.size()==0){
				rm.setState("500");
				rm.setMsgInfo("横剪计划["+pc.getCl_plan_no()+"]信息不存在!");
				return rm;
			}
			if("0PCL01".equals(lp.get(0).getStatus())){
				rm.setState("500");
				rm.setMsgInfo("横剪计划["+pc.getCl_plan_no()+"]尚未下发，不能取消!");
				return rm;
			}
			if("0PCL03".equals(lp.get(0).getStatus())){
				rm.setState("500");
				rm.setMsgInfo("横剪计划["+pc.getCl_plan_no()+"]内的某些母卷已开始作业,不能取消!");
				return rm;
			}

			// 详表 使用实物状态
			// 5BCL01 横剪计划已编制
			// 5BCL02 横剪计划已下发
			// 5BCL03 开始横剪作业
			// 5BCL09 横剪剪废
			// 5BCL10 横剪作业完成
			// 5BCL33 等待横剪判定
			// 5BCL40 横剪判定完成
			// 0PCLXX 横剪计划已失效
			PlnCuttolengthPlanDetail plpt = new PlnCuttolengthPlanDetail();
			plpt.setCl_plan_no(pc.getCl_plan_no());
			List<PlnCuttolengthPlanDetail> plnpd = this.getMapper(PlnCuttolengthPlanDetailMapper.class).findWithCondition(plpt, "status <> '0PCLXX'", null, 0, 0);
			if (plnpd != null && plnpd.size()>0) {
				for (PlnCuttolengthPlanDetail plnLe : plnpd) {
					if (!"5BCL02".equals(plnLe.getStatus())) {
						rm.setState("500");
						rm.setMsgInfo("横剪计划["+pc.getCl_plan_no()+"]内的某些母卷已开始作业,不能取消!");
						return rm;
					}
				}
			}

			//实际上包含了母卷跟子卷
			PlnCuttolengthPlanDetail plpd=new PlnCuttolengthPlanDetail();
			plpd.setCl_plan_no(pc.getCl_plan_no());
			pc.setChild(this.getMapper(PlnCuttolengthPlanDetailMapper.class).find(plpd, 0, 0));
		}


		for(PlnCuttolengthPlan pc:lplp){
			//修改横剪计划表： 相关计划的状态给为：0PCL01																					
			pc.setStatus("0PCL01");
			this.getMapper(PlnCuttolengthPlanMapper.class).doUpdate(pc);

			//修改横剪计划明细表：计划内的的各母卷分别修改状态为：5BCL01																					
			for(PlnCuttolengthPlanDetail pcc:pc.getChild()){
				pcc.setStatus("5BCL01");
				//修改横剪计划明细表：计划内的的各母卷分别修改状态为：5BCL01			
				//清空下发时间下发人
				pcc.setSender(null);
				pcc.setSend_date(null);
				this.getMapper(PlnCuttolengthPlanDetailMapper.class).doUpdateStatus(pcc);
				//虚拟物料表：修改母卷状态
				PlnMaterielDetail pmdu=new PlnMaterielDetail();
				pmdu.setCl_plan_no(pcc.getCl_plan_no());
				pmdu.setStatus("0PCL01");
				pmdu.setObject_no_vt(pcc.getObject_no_vt());
				this.getMapper(PlnMaterielDetailMapper.class).doUpdateClPlanNo(pmdu);
				
				// 修改虚拟物料子卷状态
				PlnMaterielDetail child =new PlnMaterielDetail();
				child.setCl_plan_no(pcc.getCl_plan_no());
				child.setMat_object_no_vt(pcc.getObject_no_vt());
				child.setStatus("0PCL01");
				this.getMapper(PlnMaterielDetailMapper.class).updateClByMat_No(child);
				//写虚拟物料履历，状态填:0PCL01		母卷跟子卷信息																			
				this.getBean(MesApiServiceImpl.class).InsertMatVtProc(pcc.getObject_no_vt(), "0PCL01", userName, new Date());
				
				// 撤销实物进程跟踪调用生产计划模块物料跟踪撤销接口
				PrcMaterielProcess pmp=new PrcMaterielProcess();
				pmp.setObject_no(pcc.getObject_no());
				pmp.setPrc_code("5BCL02");//新增的状态
				pmp.setRemark("计划取消下发");
				pmp.setKeep_sametime_status(0);
				//撤销实物物料状态跟踪函数:
				String tmp=this.getBean(MesApiServiceImpl.class).ARRAYLIST(pmp).getState();
			}
		}

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


	/**
	 * 报表导出
	 * */
	public ResultModel doExportCompletePlanWeb(CommonPage<PlnCuttolengthDsnMain> sum){
		ResultModel rm=new ResultModel();
		try{
			// 1，创建一个webbook，对应一个Excel文件
			WritableWorkbook workbook;
			//2,设置用户下载路径
			String path = this.getRequest().getServletContext().getRealPath("/")+ "excel" + File.separator;  //临时保存路径
			File dir = new File(path);
			if(!dir.exists()) {
				new File(path).mkdir();
			}
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
			SimpleDateFormat stdSdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String sTime=sum.getStartTime();
			if(sTime!=null&&sTime.length()>1){
				Date sDate=sdf.parse(sTime);
				sTime=sdf.format(sDate);
			}
			String eTime=sum.getEndTime();
			if(eTime!=null&&eTime.length()>1){
				Date eDate=sdf.parse(eTime);
				eTime=sdf.format(eDate);
			}
			String filename = sTime +"至"+ eTime +  "已编制横剪计划报表";
			String file=filename+".xls";  //文件名
			//3. 操作EXCEL文件
			workbook = Workbook.createWorkbook(new File(path+file));
			WritableSheet sheet = workbook.createSheet(filename, 1);
			//行高
			sheet.getSettings().setDefaultRowHeight(300);
			//列宽
			sheet.setColumnView(0,5);
			sheet.setColumnView(1,18);
			sheet.setColumnView(2,22);
			sheet.setColumnView(3,30);
			sheet.setColumnView(4,18);
			sheet.setColumnView(5,15);		//状态
			sheet.setColumnView(6,20);		//虚拟母卷号
			sheet.setColumnView(7,15);		//实物卷号
			sheet.setColumnView(8,18);
			sheet.setColumnView(9,20);
			sheet.setColumnView(10,10);		//销售备注
			sheet.setColumnView(11,10);
			sheet.setColumnView(12,10);		//产线
			sheet.setColumnView(13,10);		//机台
			sheet.setColumnView(20,15);		//横剪规格
			sheet.setColumnView(23,15);		//最早交货日期
			sheet.setColumnView(24,15);		//最晚交货日期
			sheet.setColumnView(26,20);		//创建时间
			sheet.setColumnView(27,20);		//生产时间			
			//字体  参数可自行配置
			WritableFont font1 = new WritableFont(WritableFont.ARIAL,11,WritableFont.BOLD,false,UnderlineStyle.NO_UNDERLINE);  
			WritableCellFormat cellFormat1 = new WritableCellFormat(font1); 
			cellFormat1.setAlignment(Alignment.CENTRE);
			cellFormat1.setVerticalAlignment(VerticalAlignment.CENTRE);
			//表头
			sheet.mergeCells(0, 0, 0, 1);
			sheet.addCell(new Label(0,0,"序号",cellFormat1));
			sheet.mergeCells(1, 0, 1, 1);
			sheet.addCell(new Label(1,0,"合同号",cellFormat1));
			sheet.mergeCells(2, 0, 2, 1);
			sheet.addCell(new Label(2,0,"订单号",cellFormat1));
			sheet.mergeCells(3, 0, 3, 1);
			sheet.addCell(new Label(3,0,"客户名称",cellFormat1));
			sheet.mergeCells(4, 0, 4, 1);
			sheet.addCell(new Label(4,0,"横剪计划号",cellFormat1));
			sheet.mergeCells(5, 0, 5, 1);
			sheet.addCell(new Label(5,0,"状态",cellFormat1));
			sheet.mergeCells(6, 0, 6, 1);
			sheet.addCell(new Label(6,0,"虚拟母卷号(母卷)",cellFormat1));
			sheet.mergeCells(7, 0, 7, 1);
			sheet.addCell(new Label(7,0,"实物卷号",cellFormat1));
			sheet.mergeCells(8, 0, 8, 1);
			sheet.addCell(new Label(8,0,"原料卷号",cellFormat1));
			sheet.mergeCells(9, 0, 9, 1);
			sheet.addCell(new Label(9,0,"销售备注",cellFormat1));
			sheet.mergeCells(10, 0, 10, 1);
			sheet.addCell(new Label(10,0,"加工计划备注",cellFormat1));
			sheet.mergeCells(11, 0, 11, 1);
			sheet.addCell(new Label(11,0,"产线",cellFormat1));
			sheet.mergeCells(12, 0, 12, 1);
			sheet.addCell(new Label(12,0,"机台",cellFormat1));
			sheet.mergeCells(13, 0, 13, 1);
			sheet.addCell(new Label(13,0,"牌号",cellFormat1));
			sheet.mergeCells(14, 0, 14, 1);
			sheet.addCell(new Label(14,0,"重量",cellFormat1));
			sheet.mergeCells(15, 0, 18, 0);
			sheet.addCell(new Label(15,0,"母卷规格",cellFormat1));
			sheet.addCell(new Label(15,1,"厚度",cellFormat1));
			sheet.addCell(new Label(16,1,"宽度",cellFormat1));
			sheet.addCell(new Label(17,1,"内径",cellFormat1));
			sheet.addCell(new Label(18,1,"外径",cellFormat1));
			sheet.mergeCells(19, 0, 19, 1);
			sheet.addCell(new Label(19,0,"横剪数",cellFormat1));
			sheet.mergeCells(20, 0, 20, 1);
			sheet.addCell(new Label(20,0,"横剪规格",cellFormat1));
			sheet.mergeCells(21, 0, 21, 1);
			sheet.addCell(new Label(21,0,"切边方式",cellFormat1));
			sheet.mergeCells(22, 0, 22, 1);
			sheet.addCell(new Label(22,0,"横切方式",cellFormat1));
			sheet.mergeCells(23, 0, 23, 1);
			sheet.addCell(new Label(23,0,"最早交货日期",cellFormat1));
			sheet.mergeCells(24, 0, 24, 1);
			sheet.addCell(new Label(24,0,"最晚交货日期",cellFormat1));
			sheet.mergeCells(25, 0, 25, 1);
			sheet.addCell(new Label(25,0,"创建人",cellFormat1));
			sheet.mergeCells(26, 0, 26, 1);
			sheet.addCell(new Label(26,0,"创建时间",cellFormat1));
			sheet.mergeCells(27, 0, 27, 1);
			sheet.addCell(new Label(27,0,"生产时间",cellFormat1));
//			sheet.mergeCells(28, 0, 28, 1);
//			sheet.addCell(new Label(28,0,"合计",cellFormat1));

			WritableFont font = new WritableFont(WritableFont.ARIAL,11,WritableFont.NO_BOLD,false,UnderlineStyle.NO_UNDERLINE);  
			WritableCellFormat cellFormat = new WritableCellFormat(font); 
			cellFormat.setAlignment(Alignment.CENTRE);
			cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE);

			//获取查询结果
			rm=doQueryCompletePlanWeb(sum);
			if("500".equals(rm.getState())) return rm;
			List<PlnCuttolengthDsnMainSum> list=(List<PlnCuttolengthDsnMainSum>) rm.getData();
			Double total_weight=0d;
			for(int v=0;v<list.size();v++){
				PlnCuttolengthDsnMainSum main=list.get(v);
				sheet.addCell(new Label(0,v+2,""+(v+1),cellFormat));
				if(main.getContract_no() != null ) {
					sheet.addCell(new Label(1,v+2,main.getContract_no(),cellFormat));
				}
				if(main.getOrder_no() != null) {
					sheet.addCell(new Label(2,v+2,main.getOrder_no(),cellFormat));
				}
				if(main.getCustomer_name() != null) {
					sheet.addCell(new Label(3,v+2,main.getCustomer_name(),cellFormat));
				}
				if(main.getCl_plan_no() != null) {
					sheet.addCell(new Label(4,v+2,main.getCl_plan_no(),cellFormat));
				}
				String status_content="";
				if("5BCL10".equals(main.getStatus())) status_content="横剪作业完成";
				if("5BCL01".equals(main.getStatus())) status_content="计划已编制";
				if("5BCL02".equals(main.getStatus())) status_content="计划已下发";
				if("5BCL03".equals(main.getStatus())) status_content="开始横剪作业";
				sheet.addCell(new Label(5,v+2,status_content,cellFormat));
				if(main.getObject_no_vt() != null ) {
					sheet.addCell(new Label(6,v+2,main.getObject_no_vt(),cellFormat));
				}
				if(main.getObject_no() != null ) {
					sheet.addCell(new Label(7,v+2,main.getObject_no(),cellFormat));
				}
				if(main.getMaterailcoilno() != null ) {
					sheet.addCell(new Label(8,v+2,main.getMaterailcoilno(),cellFormat));
				}
				if(main.getOrder_memo() != null) {
					sheet.addCell(new Label(9,v+2,main.getOrder_memo(),cellFormat));
				}
				if(main.getProcessMemo() != null ) {
					sheet.addCell(new Label(10,v+2,main.getProcessMemo(),cellFormat));
				}
				if(main.getPline_name() != null ) {
					sheet.addCell(new Label(11,v+2,main.getPline_name(),cellFormat));
				}
				if(main.getMachine_name() != null ) {
					sheet.addCell(new Label(12,v+2,main.getMachine_name(),cellFormat));
				}
				if(main.getSteel_name() != null ) {
					sheet.addCell(new Label(13,v+2,main.getSteel_name(),cellFormat));
				}
				if(main.getSingle_weight() != null ) {
					sheet.addCell(new Label(14,v+2,main.getSingle_weight(),cellFormat));
					double weight=Double.parseDouble(main.getSingle_weight());
					total_weight+=weight;
				}
				if(main.getThick() != null ) {
					sheet.addCell(new Label(15,v+2,main.getThick(),cellFormat));
				}
				if(main.getWidth() != null ) {
					sheet.addCell(new Label(16,v+2,main.getWidth(),cellFormat));
				}
				if(main.getDiameter_inn() != null) {
					sheet.addCell(new Label(17,v+2,main.getDiameter_inn(),cellFormat));
				}
				if(main.getDiameter_out() != null) {
					sheet.addCell(new Label(18,v+2,main.getDiameter_out(),cellFormat));
				}
				if(main.getSub_count() != null) {
					sheet.addCell(new Label(19,v+2,main.getSub_count(),cellFormat));
				}
				if(main.getCut_style() != null) {
					sheet.addCell(new Label(20,v+2,main.getCut_style(),cellFormat));
				}
				String content="";
				if("102501".equals(main.getCut_edge_type_no())) content="四毛";
				if("102502".equals(main.getCut_edge_type_no())) content="二切";
				if("102503".equals(main.getCut_edge_type_no())) content="四切";
				sheet.addCell(new Label(21,v+2,content,cellFormat));

				if(main.getCrosscut_style()==null) main.setCrosscut_style("不横切");
				sheet.addCell(new Label(22,v+2,main.getCrosscut_style(),cellFormat));
				if(main.getDeliver_date_earliest() != null) {
					sheet.addCell(new Label(23,v+2,main.getDeliver_date_earliest(),cellFormat));
				}
				if(main.getDeliver_date_latest() != null) {
					sheet.addCell(new Label(24,v+2,main.getDeliver_date_latest(),cellFormat));
				}
				if(main.getCreate_man_name() != null ) {
					sheet.addCell(new Label(25,v+2,main.getCreate_man_name(),cellFormat));
				}
				if(main.getCreate_time() != null ) {
					Date createDate=stdSdf.parse(main.getCreate_time());
					String create_time=stdSdf.format(createDate);
					sheet.addCell(new Label(26,v+2,create_time,cellFormat));
				}
				if(main.getFeeding_time() != null ) {
					Date feedingDate=stdSdf.parse(main.getFeeding_time());
					String feeding_time=stdSdf.format(feedingDate);
					sheet.addCell(new Label(27,v+2,feeding_time,cellFormat));
				}
			}
//			sheet.mergeCells(0, list.size()+2, 0, 1);
			sheet.addCell(new Label(0,list.size()+2,"合计",cellFormat1));
			sheet.addCell(new Label(14,list.size()+2,String.valueOf(total_weight),cellFormat));
			sheet.getSettings().setVerticalFreeze(1);  		//首行冻结
			sheet.getSettings().setVerticalFreeze(2);

			//关闭
			workbook.write();
			workbook.close();

			rm.setData("/download?filename="+file);
			rm.setState("200");
		}catch(Exception ex){
			rm.setState("500");
			rm.setMsgInfo(ex.getMessage());
			ex.printStackTrace();
		}
		return rm;
	}
	/**
	 * @return 计划号和序列号
	 */
	public  PlnCuttolengthPlan getPlanNo(){

		String Dt=new SimpleDateFormat("yyMMdd").format(new Date());
		//开平计划表： 开平计划号(CL+15位流水); 其他字段参考																					
		PlnCuttolengthPlan pp=new PlnCuttolengthPlan();
		//倒叙找到最后一条数据
		List<PlnCuttolengthPlan> lpp=this.getMapper(PlnCuttolengthPlanMapper.class).findWithCondition(null, "", " serial_no desc ", 0, 1);
		if(lpp==null||lpp.size()==0){
			pp.setSerial_no(1l);
			pp.setCl_plan_no("Cl"+Dt+String.format("%03d", 1));//Cl180531001 
		}else{
			pp.setSerial_no(lpp.get(0).getSerial_no()+1);
			if(Dt.equals(lpp.get(0).getCl_plan_no().substring(2,8))){
				pp.setCl_plan_no("Cl"+Dt+String.format("%03d", Integer.parseInt(lpp.get(0).getCl_plan_no().substring(8,lpp.get(0).getCl_plan_no().length()))+1 ));
			}else{
				pp.setCl_plan_no("Cl"+Dt+String.format("%03d", 1));
			}
		}
		return pp;
	}


	/**
	 * 开平计划明细表：对选中的母卷增加明细记录
	 * 修改虚拟物料信息  写虚拟履历
	 * @param plnmd 虚拟物料号、计划号
	 * @param userName
	 */
	public void doAddDetail(PlnMaterielDetail plnmd, String userName,String memo2,String memo6){

		PlnCuttolengthPlan plpl = new PlnCuttolengthPlan();
		plpl.setCl_plan_no(plnmd.getCl_plan_no());
		List<PlnCuttolengthPlan> lplp=this.getMapper(PlnCuttolengthPlanMapper.class).find(plpl, 0, 1);

		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(plnmd.getObject_no_vt());
		List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).find(pmd, 0, 0);
		pmd = lpmdq.get(0);
		List<PlnCuttolengthPlanDetail> lppd=this.getMapper(PlnCuttolengthPlanDetailMapper.class).findWithCondition(null, "", " serial_no desc ", 0, 1);
		long sNo=0;
		if(lppd==null||lppd.size()==0){
			sNo=1;
		}else{
			sNo=lppd.get(0).getSerial_no()+1;
		}
		int isqe=0;

		PlnCuttolengthPlanDetail plpdq=new PlnCuttolengthPlanDetail();
		plpdq.setCl_plan_no(plnmd.getCl_plan_no());
		lppd=this.getMapper(PlnCuttolengthPlanDetailMapper.class).findWithCondition(plpdq, "", " Cl_seq desc ", 0, 1);
		if(lppd==null||lppd.size()==0){
			isqe=1;
		}else{
			isqe=lppd.get(0).getCl_seq()+1;
		}

		PlnCuttolengthPlanDetail plpd=new PlnCuttolengthPlanDetail();
		plpd.setSerial_no(sNo++);
		plpd.setCl_plan_no(plnmd.getCl_plan_no());
		plpd.setCl_seq(isqe++);
		plpd.setObject_no_vt(pmd.getObject_no_vt());
		plpd.setCl_design_no(pmd.getCl_design_no());
		plpd.setStatus("5BCL01");
		plpd.setObject_no(pmd.getObject_no());
		plpd.setPline_code(pmd.getPline_code());
		plpd.setMachine_code(memo2);
		plpd.setSteel_code(pmd.getSteel_code());
		plpd.setMat_width(pmd.getWidth());
		plpd.setMat_thick(pmd.getThick());
		plpd.setMat_diameter_inn(pmd.getDiameter_inn());
		plpd.setMat_diameter_out(pmd.getDiameter_out());
		plpd.setMat_length(pmd.getLength());
		plpd.setMat_single_weight(pmd.getSingle_weight());
		plpd.setPlan_opt_time(lplp.get(0).getStart_time());
		plpd.setCreate_man_name(userName);
		plpd.setCreate_time(new Date());
		// 主计划
		if(Utils.isNotEmpty(pmd.getIs_main_mat()) && pmd.getIs_main_mat() ==1 ) {
			plpd.setIs_bales(1);
			plpd.setIs_main_plan(1);
		}
		// 捆包
		if(Utils.isNotEmpty(lplp.get(0).getIs_bales()) && lplp.get(0).getIs_bales() == 1) {
			plpd.setIs_bales(1);
		}
		PlnCuttolengthDsnMain pldm=new PlnCuttolengthDsnMain();
		pldm.setCl_design_no(pmd.getCl_design_no());
		List<PlnCuttolengthDsnMain> lpldm=this.getMapper(PlnCuttolengthDsnMainMapper.class).find(pldm, 0, 1);
		plpd.setRate(lpldm.get(0).getProd_rate());
		plpd.setSub_count(lpldm.get(0).getSub_count().intValue());
		plpd.setPlan_hand_time(memo6);//计划交工时间
		this.getMapper(PlnCuttolengthPlanDetailMapper.class).insert(plpd);

		//虚拟物料表：修改母卷的 开平计划号[Cl_PLANNO]字段
		PlnMaterielDetail pmdu=new PlnMaterielDetail();
		pmdu.setCl_plan_no(plnmd.getCl_plan_no());
		pmdu.setSerial_no(pmd.getSerial_no());
		pmdu.setMachine_code(memo2);
		pmdu.setStatus("0PCL01");
		this.getMapper(PlnMaterielDetailMapper.class).update(pmdu);
		
		// 修改虚拟物料子卷开平计划号
		PlnMaterielDetail child =new PlnMaterielDetail();
		child.setCl_plan_no(plnmd.getCl_plan_no());
		child.setMat_object_no_vt(pmd.getObject_no_vt());
		child.setStatus("0PCL01");
		// child.setMachine_code(memo2);
		this.getMapper(PlnMaterielDetailMapper.class).updateClByMat_No(child);

		//写虚拟物料履历，状态填:0PCl01 母卷																			
		this.getBean(MesApiServiceImpl.class).InsertMatVtProc(pmd.getObject_no_vt(), "0PCL01", userName, new Date());
		// 查询子卷
		List<PlnMaterielDetail> listchild = this.getMapper(
				PlnMaterielDetailMapper.class).findWithCondition(null,
				" mat_object_no_vt = '" + pmd.getObject_no_vt() + "'", null, 0,0);
		if (Utils.isNotEmpty(listchild)) {
			for (PlnMaterielDetail pln : listchild) {
				// 写虚拟物料履历，状态填:0PCL01 子卷
				this.getBean(MesApiServiceImpl.class).InsertMatVtProc(
						pln.getObject_no_vt(), "0PCL01", userName, new Date());
			}
		}
	}


	// -----------------------------------------------------公共验证条件的方法-----------------------------------------

	// 判断验证横剪/开平作业计划主记录存在
	public String ifplan(String vMchCode, String vPlanNo) {
		String v_ret = "";
		PlnCuttolengthPlan plan = new PlnCuttolengthPlan();
		plan.setMachine_code(vMchCode);
		plan.setCl_plan_no(vPlanNo);
		int v_cnt = this.getBean(PlnCuttolengthPlanMapper.class).count(plan);
		if (v_cnt <= 0) {
			v_ret = ("机台代码：" + vMchCode + "作业计划号:" + vPlanNo + "，作业计划主记录不存在！");
			return v_ret;
		}
		return v_ret;
	}

	// 开平作业计划详细记录存在
	public String ifplanDetail(String vMchCode, String vPlanNo,
			String vObjectNoVt, String vMaterialNo) {
		String v_ret = "";
		PlnCuttolengthPlanDetail cuttdel = new PlnCuttolengthPlanDetail();
		cuttdel.setMachine_code(vMchCode);
		cuttdel.setCl_plan_no(vPlanNo);
		cuttdel.setObject_no_vt(vObjectNoVt);
		cuttdel.setObject_no(vMaterialNo);
		int v_cnt = this.getBean(PlnCuttolengthPlanDetailMapper.class)
				.count(cuttdel);
		if (v_cnt <= 0) {
			v_ret = ("机台代码：" + vMchCode + "\n作业计划号：" + vPlanNo + "\n虚拟卷号："
					+ vObjectNoVt + "\n原料卷号：" + vMaterialNo + "\n作业计划明细记录不存在!");
			return v_ret;
		}
		return v_ret;
	}

	

	// 验证原料卷对应的横剪/开平主实绩存在，且为“未交工”状态 mes_cr_cross_cutting_m
	public String isNotFinsh(String vMchCode, String vPlanNo,
			String vObjectNoVt, String vMaterialNo) {
		String v_ret = "";
		MesCrCrossCuttingM cuttingM = new MesCrCrossCuttingM();
		cuttingM.setMachine_code(vMchCode);
		cuttingM.setSchedule_no(vPlanNo);
		cuttingM.setMaterial_no_vt(vObjectNoVt);
		cuttingM.setMaterial_no(vMaterialNo);
		// into 给新的字段赋值
		int v_cnt = this.getBean(MesCrCrossCuttingMMapper.class).count(cuttingM);
		if (v_cnt <= 0) {
			v_ret = ("原料卷号：" + vMaterialNo + "，当前不存在开平作业主实绩，请确认是否已操作上料！");
			return v_ret;
		}
		return v_ret;
	}

	// 验证机台基础信息存在
	public String ifbaseFinsh(String vMchCode) {
		String v_ret = "";
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(vMchCode);
		int v_cnt = this.getBean(ComBaseMachineMapper.class).count(machine);
		if (v_cnt <= 0) {
			v_ret = ("机台代码：" + vMchCode + "机台基础信息不存在！");
		}
		return v_ret;
	}

	// 补零
	public static String lpad(String str, int num, String pad) {
		String n_str = str;
		if (str == null && "".equals(str))
			n_str = " ";
		for (int i = str.length(); i < num; i++) {
			n_str = pad + n_str;
		}
		return n_str;
	}
 
	//判断String 是否为空
	 public String isEmpty(String b){
		 if(!"".equals(b)&& b!=null){
			 return b;
		 }else{
			 return null; 
		 }
	 }
	 
	/**
	 * 编制计划 判断虚拟物料号
	 * @param Object_no_vt
	 * @return
	 */
	public ResultModel doPlanJudgeByObject_no_vt(String Object_no_vt) {
		ResultModel rm = new ResultModel();
		// 查询虚拟卷
		PlnMaterielDetail pmd = new PlnMaterielDetail();
		pmd.setObject_no_vt(Object_no_vt);
		List<PlnMaterielDetail> lpmdq = this.getMapper(
				PlnMaterielDetailMapper.class).find(pmd, 0, 0);

		if (lpmdq == null || lpmdq.size() == 0) {
			rm.setState("500");
			rm.setMsgInfo("虚拟物料[" + Object_no_vt + "]信息不存在!");
			return rm;
		}
		// 实际上只有一条
		for (PlnMaterielDetail pmdq : lpmdq) {
			if (!"".equals(pmdq.getCl_plan_no())
					&& pmdq.getCl_plan_no() != null) {
				rm.setState("500");
				rm.setMsgInfo("虚拟物料[" + Object_no_vt + "]已经在计划["
						+ pmdq.getCl_plan_no() + "]内，无法再次编制！");
				return rm;
			}

			PlnCuttolengthPlanDetail ppd = new PlnCuttolengthPlanDetail();
			ppd.setObject_no_vt(pmdq.getObject_no_vt());
			int icount = this.getMapper(PlnCuttolengthPlanDetailMapper.class)
					.countWithCondition(ppd, " STATUS != '0PLWXX' ");
			if (icount > 0) {
				rm.setState("500");
				rm.setMsgInfo("虚拟物料[" + Object_no_vt + "]已经在计划["
						+ pmdq.getCl_plan_no() + "]内，无法再次编制！");
				return rm;
			}
			// 若虚拟物料表的 (OPT_TIMES >=1 AND NEED_EXTOPT =0) ,则报错退出
			if (pmdq.getOpt_times() != null && pmdq.getOpt_times() >= 1
					&& "1".equals(pmdq.getNeed_extopt())) {
				rm.setState("500");
				rm.setMsgInfo("虚拟物料[" + Object_no_vt + "]已经生产完毕，不能编制计划！");
				return rm;
			}
		}
		rm.setState("200");
		return rm;
	}
	
	
	/**
	 * 编制捆包计划
	 * 				将传入的物料编制到同一个计划
	 * 				先将原有虚拟子卷信息置为无效,重新生成虚拟子卷信息挂到第一个虚拟母卷下标记为主物料
	 * 				主物料对应的明细计划标记为主计划
	 * 				
	 * @param oci
	 * @return
	 * @throws Exception 
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel bales(CommonPage<PlnMaterielDetail> oci) throws Exception {

		ResultModel rm = new ResultModel("200", "编制捆包计划成功!");
		if (Utils.isEmpty(oci.getMemo2())) {
			oci.setMemo2("M0003");
		}
		
		List<PlnMaterielDetail> lpmd=oci.getObjectList();
		double wgt = 0d;
		List<PlnMaterielDetail> tmp = this.getMapper(PlnMaterielDetailMapper.class)
				.findWithCondition(null, "object_no_vt ='"+lpmd.get(0).getObject_no_vt()+"' and nvl(invalid_flg,0)=0", null, 0, 1);
		
		for(PlnMaterielDetail pmd : lpmd) {
			// 获取实物重量之和
			List<PlnMaterielDetail> pmds = this.getMapper(PlnMaterielDetailMapper.class)
			.findWithCondition(null, "object_no_vt ='"+pmd.getObject_no_vt()+"' and nvl(invalid_flg,0)=0", null, 0, 1);
			// 生产订单号必须一致
			if(!tmp.get(0).getProd_order_no().equals(pmds.get(0).getProd_order_no())) {
				rm.setState("500");
				rm.setMsgInfo("订单一致的物料才能组到一个捆包!请重新选择!");
				return rm ;
			}
			wgt += pmds.get(0).getSingle_weight();
			// 将母卷的虚拟子卷信息置为无效
			this.getMapper(PlnMaterielDetailMapper.class).MatToInvalid(pmd.getObject_no_vt());
		}
		// 将虚拟物料标记为主物料
		PlnMaterielDetail pm_tmp = new PlnMaterielDetail() ;
		pm_tmp.setIs_main_mat(1);
		pm_tmp.setSerial_no(tmp.get(0).getSerial_no());
		this.getMapper(PlnMaterielDetailMapper.class).update(pm_tmp);
		// 重新生成虚拟物料信息
		// 生成设计信息
		this.getBean(MesApiDesignInfoImpl.class).CuttolengthPlanDsn(tmp.get(0).getProd_order_no(), tmp.get(0).getObject_no_vt(), tmp.get(0).getPrev_process_code(),
				tmp.get(0).getNext_process_code(), wgt, tmp.get(0).getObject_no(),tmp.get(0).getProc_repeat_index());
		// 编制到同一个计划
		oci.setMemo3("1");	
		oci.setMemo4("1");
		ResultModel rst = doCheckPlanAdd(oci) ;
		if("500".equals(rst.getState())) {
			return rst ; 
		}
		return rm;

	}
	
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doBales(CommonPage<PlnCuttolengthPlan> cp) throws Exception {
		ResultModel rm = new ResultModel("200", "编制捆包计划成功!");
		if (Utils.isEmpty(cp.getMemo2())) {
			cp.setMemo2("M0003");
		}
		List<PlnCuttolengthPlan> ppList = cp.getObjectList();
		if (CollectionUtils.isEmpty(ppList)) {
			throw new Exception("编制捆包号失败");
		}
		
		int i = 0;
		String mainClno = null;
		for (PlnCuttolengthPlan p : ppList) {
			if (i == 0) {
				i++;
				//将明细表修改成主信息
				mainClno = p.getCl_plan_no();
				String sql = "update pln_cuttolength_plan_detail t set t.is_bales = 1,t.is_main_plan =1, t.cl_seq = '"+i+"', t.cl_plan_no = '"+mainClno+"' where t.cl_plan_no = '"+p.getCl_plan_no()+"'";
				this.getMapper(PbModelDbMapper.class).doUpdateSql(sql);
				//修改主表
				//sql = "update mes_cr_cross_cutting_m t set t.is_bales = 1, t.is_main_plan = 1  where t.schedule_no = '"+p.getCl_plan_no()+"'";
				//this.getMapper(PbModelDbMapper.class).doUpdateSql(sql);
			}else {
				i++;
				//删除其余的主表
				String sql = "delete from pln_cuttolength_plan t where t.cl_plan_no = '"+p.getCl_plan_no()+"'";
				this.getMapper(PbModelDbMapper.class).doUpdateSql(sql);
				//修改明细表的计划号
				sql = "update pln_cuttolength_plan_detail t set t.is_bales = 1, t.cl_seq = '"+i+"', t.cl_plan_no = '"+mainClno+"' where t.cl_plan_no = '"+p.getCl_plan_no()+"'";
				this.getMapper(PbModelDbMapper.class).doUpdateSql(sql);
				//修改pln_materiel_detail
				sql = "update pln_materiel_detail t set t.cl_plan_no = '"+mainClno+"' where t.cl_plan_no = '"+p.getCl_plan_no()+"'";
				this.getMapper(PbModelDbMapper.class).doUpdateSql(sql);
				//修改主表
				//sql = "update mes_cr_cross_cutting_m t set t.is_bales = 1,t.schedule_no = '"+mainClno+"',t.inner_seq = '"+i+"' where t.schedule_no = '"+p.getCl_plan_no()+"'";
				//this.getMapper(PbModelDbMapper.class).doUpdateSql(sql);				
			}		
		}
		return rm;
	}

}



