/***文档注释***********************************************
 * 作者            ：
 * 创建日期     ：2019-04-25
 * 描述            ：酸洗生产主实绩
 * 注意事项     ：
 * 遗留BUG   ：
 * 修改日期     ：
 * 修改人员     ：
 * 修改内容     ：
***********************************************************/
package market.Mes.Pickle.Performance.impl;

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

import market.Api.Lms.impl.LmsApiServiceImpl;
import market.Api.Lms.impl.LmsMesApiServiceImpl;
import market.Api.Mes.impl.MesApiDesignInfoImpl;
import market.Api.Mes.impl.MesApiPicklePlanServiceImpl;
import market.Api.Mes.impl.MesApiServiceImpl;
import market.Api.Mes.impl.ProcessPoint;
import market.Api.Mes.impl.Utils;
import market.Api.Qms.impl.QmsApiServiceImpl;
import market.Api.Qms.vo.JudgeResult;
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.Lengthwise.Performance.vo.MesPrdDetailReport;
import market.Mes.Lengthwise.Plan.mapper.PlnMaterielDetailMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnProcessPlanMapper;
import market.Mes.Lengthwise.Plan.vo.PlnMaterielDetail;
import market.Mes.Lengthwise.Plan.vo.PlnProcessPlan;
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.PlnProdorderMapper;
import market.Mes.OrderManager.Plan.vo.PlnProdorder;
import market.Mes.Pickle.Performance.mapper.MesPlmDMapper;
import market.Mes.Pickle.Performance.mapper.MesPlmDParMapper;
import market.Mes.Pickle.Performance.mapper.MesPlmMMapper;
import market.Mes.Pickle.Performance.mapper.MesPlmWgtMapper;
import market.Mes.Pickle.Performance.mapper.Tbs02L2PltcmProSeqMapper;
import market.Mes.Pickle.Performance.mapper.Tbs02L2PltcmReceiveDataMapper;
import market.Mes.Pickle.Performance.service.MesPlmMService;
import market.Mes.Pickle.Performance.vo.MesPlmD;
import market.Mes.Pickle.Performance.vo.MesPlmDPar;
import market.Mes.Pickle.Performance.vo.MesPlmM;
import market.Mes.Pickle.Performance.vo.MesPlmMAndListMesDPass;
import market.Mes.Pickle.Performance.vo.MesPlmWgt;
import market.Mes.Pickle.Performance.vo.PlnPicklePlanDetailAndMesPlmD;
import market.Mes.Pickle.Performance.vo.PlnPlmView;
import market.Mes.Pickle.Performance.vo.Tbs02L2PltcmProSeq;
import market.Mes.Pickle.Performance.vo.Tbs02L2PltcmReceiveData;
import market.Mes.Pickle.Plan.mapper.PlnPicklePlanDetailMapper;
import market.Mes.Pickle.Plan.mapper.PlnPicklePlanMapper;
import market.Mes.Pickle.Plan.vo.PlnPicklePlan;
import market.Mes.Pickle.Plan.vo.PlnPicklePlanDetail;
import market.Qms.qcm.service.impl.QcmJhySampleConsignDItemServiceImpl;
import market.Qms.qcm.vo.QcmJhySampleFromPlan;
import market.Slm.ContractManagement.mapper.SlmContractLineInfoMapper;
import market.Slm.ContractManagement.vo.SlmContractLineInfo;
import market.Slm.FundManagement.impl.SlmFundFirstDetailServiceImpl;
import market.Slm.FundManagement.service.SlmFundFirstDetailService;

import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

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


@RemoteService(path="MesPlmMService")
public class MesPlmMServiceImpl extends BaseServiceImpl<MesPlmM,Object> implements MesPlmMService {
	
	
	/**
	 * 酸洗 ：各机组生产明细报表
	 * memo1:机台代码
	 * startTime:计划下发时间开始
	 * endTime:计划下发时间结束
	 * startTime2:交工时间开始
	 * endTime2:交工时间结束
	 * memo2:生产时间开始
	 * meme3:生产时间结束
	 * memo4:交货时间开始
	 * memo5:交货时间结束
	 * */
	public ResultModel doPrdDetailWeb_rcm(CommonPage<MesPrdDetailReport> oci){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesPlmMMapper.class).doPrdDetailWeb_plm(oci.getObject(),oci.getMemo1(),oci.getStartTime(),oci.getEndTime(),
					oci.getStartTime2(),oci.getEndTime2(),oci.getMemo2(),oci.getMemo3(),oci.getMemo4(),oci.getMemo5()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	
	
	/**
	 * 酸洗产量报表
	 * 根据班次统计报表
	 * */
	public ResultModel doProductionWrkReportWeb(CommonPage<MesPlmM> oci){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesPlmMMapper.class).doProductionWrkReport(oci.getObject()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}

	/**
	 * 各牌号酸洗产量报表
	 * */
	public ResultModel doProductionSteelReportWeb(CommonPage<MesPlmM> oci){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesPlmMMapper.class).doProductionSteelReport(oci.getObject()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}

	
	/**
	 * 展示到“当班汇总信息”区域
	 * V_MCH_CODE（机台代码）、V_WRK_DATE（登录日期）、V_WRK_ORD（登录班次）、V_WRK_GRP（登录班组）
	 * memo1-4
	 * @param oci
	 * @return
	 */
	public ResultModel doQueryWrkWeb(CommonPage<MesPlmM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			rm.setData(this.getMapper(MesPlmMMapper.class).doQueryWrkWeb(oci.getMemo1(),oci.getMemo2(),oci.getMemo3(),oci.getMemo4()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	
	/**
	    动作处理_查询按钮
	 memo1:机台代码
	 memo2：作业计划号
	 memo3:原料卷号
	 startTime：开始时间
	 endTime：结束时间
	* @param oci
	* @return
	*/
	public ResultModel doQueryWeb2(CommonPage<MesPlmM> cp){
		ResultModel rm=new ResultModel();
		try{ 
			if (StringUtils.isEmpty(cp.getStartTime()) 
					&& StringUtils.isEmpty(cp.getEndTime())
					&& StringUtils.isEmpty(cp.getMemo3())
					&& !"in".equals(cp.getMemo6())) {
				throw new Exception("请选择查询条件");
			}
			List<PlnPlmView> lpav = this.getMapper(MesPlmMMapper.class).doQueryWeb2(cp.getMemo1(),cp.getStartTime(),cp.getEndTime(),cp.getMemo2(),cp.getMemo3(),cp.getMemo6());
			rm.setData(lpav);
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**动作处理_作业计划选中行变化
	 * “酸洗生产实绩”（编辑区域）处理：
	 * memo1:机台代码
	 * memo2：作业计划号
	 * memo3:虚拟卷号
	 * @param cp
	 * @return
	 */
	public ResultModel doQueryWeb3(CommonPage<MesPlmM> cp){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesPlmMMapper.class).doQueryWeb3(cp.getMemo1(),cp.getMemo2(),cp.getMemo3()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**动作处理_作业计划选中行变化
	 * “轧制道次的处理”（编辑区域）处理：
	 * memo1:机台代码
	 * memo2：作业计划号
	 * memo3:虚拟卷号
	 * @param cp
	 * @return
	 */
	public ResultModel doQueryWeb3_Pass(CommonPage<MesPlmM> cp){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesPlmMMapper.class).doQueryWeb3_pass(cp.getMemo1(),cp.getMemo2(),cp.getMemo3()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	
	
	/***
	 * 动作处理-上料按钮     
	 * object中：
	 * Pc_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1：机台代码，
	 * memo2：登录班组，
	 * memo3:登录用户名
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doTpmInsWeb(CommonPage<PlnPicklePlan> sum) throws Exception {
		ResultModel r = new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String username = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		String 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);
		
		Integer v_cnt;
		//  --(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		// --优特钢目前3班2运转，必须按此限制
		if (sum.getMemo2() == null
				|| ((!sum.getMemo2().equals("1")) && (!sum.getMemo2().equals("2")) && (!sum.getMemo2()
						.equals("3")) && (!sum.getMemo2().equals("4"))						
						)) {
			r.setMsgInfo("班组代码：" + sum.getMemo2() + "无效，\n只能是 1（甲班）或2（乙班）或3（丙班）或4（丁班）！请选择正确的班组，重新登录系统!");
			r.setState("500");
			return r;
		}
		PlnPicklePlan plp = sum.getObject();
		if(plp.getPc_plan_no()==null || "".equals(plp.getPc_plan_no())){
			r.setMsgInfo("作业计划号为空");
			r.setState("500");
			return r;
		}
		if(plp.getObject_no_vt()==null || "".equals(plp.getObject_no_vt())){
			r.setMsgInfo("虚拟卷号为空");
			r.setState("500");
			return r;
		}
		if(plp.getMaterial_no()==null || "".equals(plp.getMaterial_no())){
			r.setMsgInfo("原料卷号为空");
			r.setState("500");
			return r;
		}
		//  --(2)、验证机台基础信息存在
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(sum.getMemo1());
		v_cnt = this.getMapper(ComBaseMachineMapper.class).count(machine);
		if (v_cnt <= 0) {
			r.setMsgInfo("机台代码：" + sum.getMemo1() + "，\n机台基础信息不存在！");
			r.setState("500");
			return r;
		}
		//  --（2.1)、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
		ComBaseMachine machine2 = new ComBaseMachine();
		machine2.setMachine_code(sum.getMemo1());
		List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class)
				.find(machine2, 0, 0);
		String v_mch_mark=lcbm.get(0).getMachine_mark();
		if (v_mch_mark == null) {
			r.setMsgInfo("机台代码：" + sum.getMemo1() + "\n设备编号未配置，无法处理！");
			r.setState("500");
			return r;
		}
		
		// --(4)、上料业务处理： 	
		//  --(4.1)、验证酸洗作业计划主记录存在
		PlnPicklePlan psp=new PlnPicklePlan();
		psp.setMachine_code(sum.getMemo1());
		psp.setPc_plan_no(plp.getPc_plan_no());
		int count = this.getMapper(PlnPicklePlanMapper.class).count(psp);
		if (count<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getPc_plan_no()+"\n作业计划主记录不存在！");
		}
		//    --(4.2)、验证酸洗作业计划明细记录存在
		PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setPc_plan_no(plp.getPc_plan_no());
		pcpd.setObject_no_vt(plp.getObject_no_vt());
		pcpd.setObject_no(plp.getMaterial_no());
		int count2 = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getPc_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
					+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
		}
				
		//    --(4.3)、验证虚拟物料表中，原料卷计划信息存在
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(plp.getObject_no_vt());
		int count3 = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if (count3<=0) {
			throw new Exception("虚拟卷号："+plp.getObject_no_vt()+"\n原料卷虚拟物料信息不存在！");
		}
				
		//	    --(4.7)、验证指定的计划，还未创建酸洗作业主实绩
		MesPlmM mCross = new MesPlmM();
		mCross.setMachine_code(sum.getMemo1());
		mCross.setSchedule_no(plp.getPc_plan_no());
		mCross.setMaterial_no_vt(plp.getObject_no_vt());
		mCross.setMaterial_no(plp.getMaterial_no());
		v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
		if (v_cnt > 0) {
			throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前已存在酸洗作业实绩！");
		}
		
		//  --(4.4)、验证原料卷号库存明细记录存在
		YdmProductDetail tYdm2 = new YdmProductDetail();
		tYdm2.setCoilno(plp.getMaterial_no());
		v_cnt = this.getMapper(YdmProductDetailMapper.class).count(tYdm2);
		if (v_cnt <= 0) {
			throw new Exception("原料卷号：" + plp.getMaterial_no() + "库存明细记录不存在！");
		}
		
		//2018-11-29 只有是已下发状态的钢卷才能下发
		PlnPicklePlanDetail cuttdel = new PlnPicklePlanDetail();
		cuttdel.setMachine_code(sum.getMemo1());
		cuttdel.setPc_plan_no(plp.getPc_plan_no());
		cuttdel.setObject_no_vt(plp.getObject_no_vt());
		cuttdel.setObject_no(plp.getMaterial_no());
		List<PlnPicklePlanDetail> v_rec_pln_d = this.getMapper(PlnPicklePlanDetailMapper.class).findWithCondition(
						cuttdel, null, null, 0, 0);
		if(v_rec_pln_d!=null && v_rec_pln_d.size()>0){
			if(!"5BPC02".equals(v_rec_pln_d.get(0).getStatus())){
				throw new Exception("当前状态{"+v_rec_pln_d.get(0).getStatus()+"}不为已下发");
			}
		}
		
		//(4.5)、验证原料卷号库存明细记录为“在库”状态   【在库状态(-1待入库、0在库、1移送在途、2发运锁定、4包装出库、5出库)】
		YdmProductDetail tYdm3 = new YdmProductDetail();
		tYdm3.setCoilno(plp.getMaterial_no());
		List<YdmProductDetail>  v_rec_ydm_d = this.getMapper(YdmProductDetailMapper.class).findWithCondition(tYdm3,
						null, null, 0, 0);
		if (v_rec_ydm_d.get(0).getState()==null || (!v_rec_ydm_d.get(0).getState().equals("0"))) {
			throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不是“在库”状态！当前状态为【"+v_rec_ydm_d.get(0).getState()+"】(-1待入库、0在库、1移送在途、2发运锁定、4包装出库、5出库)");
		}
		//    --(4.6)、验证虚拟物料表中，出口卷虚拟物料信息存在
		PlnMaterielDetail pmd2=new PlnMaterielDetail();
		pmd2.setMat_object_no_vt(plp.getObject_no_vt());
		v_cnt = this.getMapper(PlnMaterielDetailMapper.class).count(pmd2);
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+plp.getObject_no_vt()+"\n出口卷虚拟物料信息不存在！");
		}
		
		/*
		      --(4.9)、创建酸洗主实绩记录（未列出字段，表设置的缺省值）																																							
			  --(4.9.1)、原料卷计划规格、牌号等信息来源于 pln_materiel_detail 表																																							
			  --(4.9.2)、原料卷实际规格、牌号等信息来源于 ydm_product_detail 表																																							
			  --(4.9.3)、出口卷计划规格、牌号等信息来源于 pln_materiel_detail 表																																							
			  --(4.9.4)、出口卷实际规格、牌号等信息来源于 ydm_product_detail 表																																							
		 */
		PlnMaterielDetail tYdm = new PlnMaterielDetail();
		tYdm.setObject_no_vt(plp.getObject_no_vt());
		List<PlnMaterielDetail> v_rec_mtr_in = this.getBean(PlnMaterielDetailMapper.class).findWithCondition(tYdm, null, null, 0, 0);
		// 9.2 大 写字母'X' + 6位日期（YYMMDD，取数据库时间） + 2位纵剪设备编号（不足为前面补0）
		// 补零
		SimpleDateFormat formatY3 = new SimpleDateFormat("yyMMdd");
		String v_process_no = "X" + formatY3.format(now)+lpad(v_mch_mark, 2, "0");
		v_cnt = this.getMapper(MesPlmMMapper.class).doquery(v_process_no);
		if (v_cnt == null) {
			v_cnt = 1;
		}
		v_process_no = v_process_no + lpad(v_cnt.toString(), 3, "0");		
		
		MesPlmM mcam=new MesPlmM();
		mcam.setProcess_no(v_process_no);
		mcam.setMachine_code(sum.getMemo1());
		mcam.setSchedule_no(plp.getPc_plan_no());
		mcam.setInner_seq(v_rec_pln_d.get(0).getPc_seq());
		mcam.setMaterial_no_vt(plp.getObject_no_vt());
		mcam.setPln_steel_code(v_rec_mtr_in.get(0).getSteel_code());
		mcam.setPln_mtr_thk(v_rec_mtr_in.get(0).getThick());
		mcam.setPln_mtr_wdt(v_rec_mtr_in.get(0).getWidth());
		mcam.setPln_mtr_len(v_rec_mtr_in.get(0).getLength());
		mcam.setPln_mtr_inn_dia(v_rec_mtr_in.get(0).getDiameter_inn());
		mcam.setPln_mtr_out_dia(v_rec_mtr_in.get(0).getDiameter_out());
		mcam.setPln_mtr_thr_wgt(v_rec_mtr_in.get(0).getSingle_weight());
		mcam.setMaterial_no(plp.getMaterial_no());
		mcam.setMaterial_no_src(v_rec_ydm_d.get(0).getMaterailcoilno());
		mcam.setSteel_code(v_rec_ydm_d.get(0).getSteelcode());
		mcam.setMtr_thk(v_rec_ydm_d.get(0).getThick());
		mcam.setMtr_wdt(v_rec_ydm_d.get(0).getWidth());
		mcam.setMtr_len(v_rec_ydm_d.get(0).getLength());
		mcam.setMtr_inn_dia(v_rec_ydm_d.get(0).getDiameter_inn());
		mcam.setMtr_out_dia(v_rec_ydm_d.get(0).getDiameter_out());		
		mcam.setMtr_thr_wgt(v_rec_ydm_d.get(0).getTheoryweight());
		mcam.setMtr_act_wgt(v_rec_ydm_d.get(0).getFactweight());
		mcam.setWrk_date(new SimpleDateFormat("yyyy-MM-dd").format(now));
		mcam.setWrk_ord(WORK_ORD);
		mcam.setWrk_grp(WORK_GRP);
		mcam.setFeeding_time(now);
		mcam.setPartial_rejected("0");		
		mcam.setHand_over_status("0");
		mcam.setCreate_opr(vOprName);
		mcam.setCreate_time(now);		
		this.getMapper(MesPlmMMapper.class).insert(mcam);
		
		// --(4.10)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）； ？？？
		MesPlmM  mcsm=new MesPlmM();
		mcsm.setMachine_code(sum.getMemo1());//机台号
		mcsm.setSchedule_no(plp.getPc_plan_no());//作业计划号
		mcsm.setMaterial_no(plp.getMaterial_no());//投料卷号
		mcsm.setMaterial_no_vt(plp.getObject_no_vt());//虚拟卷号 
		List<MesPlmM> lmcsm=new ArrayList<MesPlmM>();
		
		//时间
	    mcsm.setMemo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(now));
	    lmcsm.add(mcsm);
	    this.getBean(MesApiPicklePlanServiceImpl.class).MesPlmMAdd(lmcsm); 
		
	    //日志
	    MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "上料", username, opr_time, null, null, null, null, "投料卷号："+mcsm.getMaterial_no());
	    this.getMapper(MesOprLogMapper.class).insert(mol);
		
		// --(5)、提交事务
		r.setState("200");
		r.setMsgInfo("上料成功!");
		return r;
	}
	
	/**
	 * 动作处理 -恢复计划 
	 * object中：
	 * Pc_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1：机台代码，
	 * memo2:登录用户名，
	 * memo3:登录班组
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doUpdateWeb(CommonPage<PlnPicklePlan> sum) throws Exception {
		ResultModel r=new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String username = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		PlnPicklePlan plp = sum.getObject();

		Integer v_cnt;				
		//  --(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}		
		if(plp.getPc_plan_no()==null || "".equals(plp.getPc_plan_no())){
			r.setMsgInfo("作业计划号为空");
			r.setState("500");
			return r;
		}
		if(plp.getObject_no_vt()==null || "".equals(plp.getObject_no_vt())){
			r.setMsgInfo("虚拟卷号为空");
			r.setState("500");
			return r;
		}
		if(plp.getMaterial_no()==null || "".equals(plp.getMaterial_no())){
			r.setMsgInfo("原料卷号为空");
			r.setState("500");
			return r;
		}
		
		// --(2)、恢复计划处理逻辑：
		// --(2.1)、验证酸洗作业计划主记录存在
		PlnPicklePlan pcp=new PlnPicklePlan();
		pcp.setMachine_code(sum.getMemo1());
		pcp.setPc_plan_no(plp.getPc_plan_no());
		int count = this.getMapper(PlnPicklePlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getPc_plan_no()+"\n作业计划主记录不存在！");
		}
		//    --(2.2)、验证酸洗作业计划明细记录存在
		PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setPc_plan_no(plp.getPc_plan_no());
		pcpd.setObject_no_vt(plp.getObject_no_vt());
		pcpd.setObject_no(plp.getMaterial_no());
		int count2 = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getPc_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
					+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
		}
		//    --(2.3)、验证虚拟物料表中，原料卷计划信息存在
		PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setObject_no_vt(plp.getObject_no_vt());
		int count3 = this.getMapper(PlnMaterielDetailMapper.class).count(pmd);
		if (count3<=0) {
			throw new Exception("虚拟卷号："+plp.getObject_no_vt()+"\n原料卷虚拟物料信息不存在！");
		}

		//    --(2.5)、验证酸洗作业主实绩存在，且为“未交工”状态
		MesPlmM mCross = new MesPlmM();
		mCross.setMachine_code(sum.getMemo1());
		mCross.setSchedule_no(plp.getPc_plan_no());
		mCross.setMaterial_no_vt(plp.getObject_no_vt());
		mCross.setMaterial_no(plp.getMaterial_no());
		v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
		if (v_cnt<=0) {
			throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在酸洗作业实绩！");
		}
	    List<MesPlmM> lmcam = this.getMapper(MesPlmMMapper.class).find(mCross, 0, 0);
	    MesPlmM v_rec_Rcm =lmcam.get(0);
	    if(v_rec_Rcm.getHand_over_status()!=null && !v_rec_Rcm.getHand_over_status().equals("0")){
			throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能恢复计划！\n可取消交工，再进行此操作！");
	    }
	    
	    // 废掉原有逻辑 需要删除主实绩和出口卷实绩 20240911刘侣
	    // 不需要删除主实绩和出口卷实绩：20220728 treals 
	    // ===start===
	    // 5.验证原料卷，当前未生成出口卷实绩
	    MesPlmD crcrD = new MesPlmD();
 		crcrD.setProcess_no(v_rec_Rcm.getProcess_no());
 		v_cnt = this.getBean(MesPlmDMapper.class).count(crcrD);
 		
 		if (v_cnt > 0) {
 			r.setMsgInfo("原料卷号：" + plp.getMaterial_no() + "已生成出口卷信息，不能恢复计划"+"\n"
 					+"可删除所有出口卷记录后，再进行此操作！");
 			r.setState("500");
 			return r;
 		}
 		// ===end===
	    
	    //--(2.6)、调用生产管理接口，验证是否能执行相关操作，如果不满足条件，返回错误信息到前端，结束操作（接口由生产管理模块提供）；	 ??																																						
	    //this.getBean(MesApiPicklePlanServiceImpl.class).MesPlmMCancelValid(lmcam);
	    //--(2.7)、调用物流模块接口，验证原料卷可撤销生产出库操作，如果不满足条件，返回错误信息到前端，结束操作（接口由物流模块提供）；		
	    
		// 酸洗是交工时才出库，所以不能这里判断是否出库了：20220728 treals
		// ===start===
// 		CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
// 		YdmProductDetail ypdu=new YdmProductDetail();
//		ypdu.setCoilno(plp.getMaterial_no());
//		cp.setObject(ypdu);
		
//		r = this.getBean(LmsApiServiceImpl.class).doDepend(cp);
//		if("500".equals(r.getState())){
//			throw new Exception(r.getMsgInfo());
//		}
		// ===end===
		
		// 废掉原有逻辑 需要删除主实绩和出口卷实绩 20240911刘侣
	    // 不需要删除酸洗主实绩：20220728 treals
	    // ===start===
		//--(2.8)、删除酸洗作业实绩
		this.getMapper(MesPlmMMapper.class).doDelete(sum.getMemo1(),v_rec_Rcm.getProcess_no());
		// ===end===
		
		// --(2.9)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）；？？																																							
		this.getBean(MesApiPicklePlanServiceImpl.class).MesPlmMCancel(lmcam);
		//日志
		MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "恢复计划", username, opr_time, plp.getMaterial_no(), null, null, null, "投料卷号："+plp.getMaterial_no());
		this.getMapper(MesOprLogMapper.class).insert(mol);
		//  --(3)、提交事务
		r.setState("200");
		r.setMsgInfo("恢复计划成功");
		return r;
	}
	
	/**
	 * 保存  * 
	 * object中：
	 * schedule_no作业计划号
	 * material_no_vt虚拟卷号
	 * material_no原料卷号
	 * 详见文档
	 * -----
	 * memo1：机台代码，
	 * memo2:登录用户名
	 * */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel  doSaveWeb(CommonPage<MesPlmMAndListMesDPass> sum) throws Exception{
		ResultModel r = new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String username = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		MesPlmM mcm = sum.getObject().getMrm();
		
		List<MesPlmDPar> listMrdp=sum.getObject().getListMrdp();
		if(mcm==null){
			r.setState("500");
			r.setMsgInfo("请传入参数！");
			return r;
		}
		Integer v_cnt;		
		// --(1)、验证酸洗作业计划主记录存在
		PlnPicklePlan pcp=new PlnPicklePlan();
		pcp.setMachine_code(sum.getMemo1());
		pcp.setPc_plan_no(mcm.getSchedule_no());
		int count = this.getMapper(PlnPicklePlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+mcm.getSchedule_no()+"\n作业计划主记录不存在！");
		}
		//    --(2.2)、验证酸洗作业计划明细记录存在
		PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setPc_plan_no(mcm.getSchedule_no());
		pcpd.setObject_no_vt(mcm.getMaterial_no_vt());
		pcpd.setObject_no(mcm.getMaterial_no());
		int count2 = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+mcm.getSchedule_no()+"\n虚拟卷号："+mcm.getMaterial_no_vt()+""
					+ "\n原料卷号："+mcm.getMaterial_no()+"\n作业计划明细记录不存在！");
		}
		//  --(3)、验证原料卷对应的酸洗主实绩存在，且为“未交工”状态
		MesPlmM mCross = new MesPlmM();
		mCross.setMachine_code(sum.getMemo1());
		mCross.setSchedule_no(mcm.getSchedule_no());
		mCross.setMaterial_no_vt(mcm.getMaterial_no_vt());
		mCross.setMaterial_no(mcm.getMaterial_no());
		v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
		if (v_cnt<=0) {
			r.setState("500");
			r.setMsgInfo("原料卷号：" +mcm.getMaterial_no()+ "，当前不存在酸洗作业实绩！");
			return r;
		}
	    List<MesPlmM> lmcam = this.getMapper(MesPlmMMapper.class).find(mCross, 0, 0);
	    MesPlmM v_rec_Rcm =lmcam.get(0);
	    if(v_rec_Rcm.getHand_over_status()!=null && !v_rec_Rcm.getHand_over_status().equals("0")){
	    	r.setState("500");
	    	r.setMsgInfo("原料卷号："+mcm.getMaterial_no()+"当前已生产交工，不能修改生产实绩！可取消交工，再进行此操作！");
			return r;
	    }
	    //  --(4)、如果前端参数 V_PARTIAL_REJECTED = '1'，表示部分原料卷吊销，则要按规则创建吊销的原料卷号信息
	    String v_rejected_coil_no=null;
	    if("1".equals(mcm.getPartial_rejected())){
	    	//    --(4.1)、验证机台基础信息存在
			ComBaseMachine machine = new ComBaseMachine();
			machine.setMachine_code(sum.getMemo1());
			v_cnt = this.getMapper(ComBaseMachineMapper.class).count(machine);
			if (v_cnt <= 0) {
				r.setMsgInfo("机台代码：" + sum.getMemo1() + "，\n机台基础信息不存在！");
				r.setState("500");
				return r;
			}
			//  --（4.2)、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
			ComBaseMachine machine2 = new ComBaseMachine();
			machine2.setMachine_code(sum.getMemo1());
			List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class)
					.find(machine2, 0, 0);
			String v_mch_mark=lcbm.get(0).getMachine_mark();
			if (v_mch_mark == null) {
				r.setMsgInfo("机台代码：" + sum.getMemo1() + "\n设备编号未配置，无法处理！");
				r.setState("500");
				return r;
			}
			//    --(4.3)、1位流水（1 - 9）：从小到大的序号排查，不存在则占用
			//String v_rejected_coil_no=null;
			for(int i=1;i<=9;i++){
				// 吊销卷编码规则：原料卷号（最初始原料卷号） + 1位工序代号（酸洗P）+ 2位设备代号（01-99）+ 'R' + 1位流水（1 - 9）
				v_rejected_coil_no=mcm.getMaterial_no().substring(0, 8) + "S"+ lpad(v_mch_mark, 2, "0")+"R"+i;
				count=this.getMapper(MesPlmMMapper.class).doCount1(v_rejected_coil_no,mcm.getSchedule_no(),mcm.getMaterial_no_vt(),mcm.getMaterial_no());
			    //  --(4.5)、吊销卷号未占用
				if(count==0){
					break;
				}
			}
	    	//    --(4.6)、吊销卷号无法生成（1-9序号全部被使用）
			if(count>0){
				r.setMsgInfo("原料卷号："+mcm.getMaterial_no()+"，部分原料卷吊销卷号生成失败，序号已全部占用！");
				r.setState("500");
				return r;
			}
	    }else if("0".equals(mcm.getPartial_rejected())){
	    	mcm.setRejected_coil_act_wgt(null);
	    	mcm.setRejected_coil_len(null);
	    	mcm.setRejected_coil_no(null);
	    	mcm.setRejected_coil_out_dia(null);
	    	mcm.setRejected_coil_thr_wgt(null);
		}
	    
	    mcm.setRejected_coil_no(v_rejected_coil_no);
	    mcm.setUpdate_opr(username);
	    mcm.setMachine_code(sum.getMemo1());
	    mcm.setProcess_no(v_rec_Rcm.getProcess_no());
	    //  --(5)、修改酸洗生产实绩主记录（所有字段都可能为空值，注意SQL的处理）
	    this.getMapper(MesPlmMMapper.class).doUpdate(mcm);
	    // （5）、新加功能：同步横剪/开平出口卷实绩作业日期、班次、班组
	    MesPlmD med=new MesPlmD();
	    med.setProcess_no(v_rec_Rcm.getProcess_no());
	    if(mcm.getWrk_date()!=null){
	    	med.setWrk_date(mcm.getWrk_date());
	    }
	    if(mcm.getWrk_ord()!=null){
	    	med.setWrk_ord(mcm.getWrk_ord());
	    }
	    if(mcm.getWrk_grp()!=null){
	    	med.setWrk_grp(mcm.getWrk_grp());
	    }
	    med.setUpdate_opr(username);
	    this.getMapper(MesPlmDMapper.class).doUpdate(med);
	    if(listMrdp!=null && listMrdp.size()>0){
	    	this.getMapper(MesPlmDParMapper.class).doDelete(v_rec_Rcm.getProcess_no());
	    	for(MesPlmDPar mrdp:listMrdp){
		    	mrdp.setUpdate_opr(username);
		    	mrdp.setUpdate_time(now);
		    	this.getMapper(MesPlmDParMapper.class).insert(mrdp);
		    }
	    }
	    
	    //日志
	    MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "保存", username, opr_time, mcm.getMaterial_no(), null, null, null, "投料卷号："+mcm.getMaterial_no());
	    this.getMapper(MesOprLogMapper.class).insert(mol);
	    
	    //--  --(6)、提交事务
	    r.setState("200");
	    r.setMsgInfo("保存成功！");
		return r;
	}
	
	
	/***
	 * 动作处理--交工按钮   
	 * object中：
	 * Pc_plan_no 作业计划号【酸洗计划号】
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOff(CommonPage<PlnPicklePlan> sum) throws Exception {
		ResultModel r=new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String userId = (String) this.getSession().getAttribute(HomeService.SESSION_USER_ID);
		String username = (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);
		PlnPicklePlan psp = sum.getObject();
		
		String nextP = "";
		
		Integer v_cnt;
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		if("".equals(psp.getPc_plan_no()) || "".equals(psp.getPc_plan_no())){
			r.setState("500");
			r.setMsgInfo("参数错误：作业计划号为空");
			return r;
		}		
		// --(1)、验证酸洗作业计划主记录存在
		PlnPicklePlan pcp=new PlnPicklePlan();
		pcp.setMachine_code(sum.getMemo1());
		pcp.setPc_plan_no(psp.getPc_plan_no());
		int count = this.getMapper(PlnPicklePlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n作业计划主记录不存在！");
		}
		//    --(2.2)、验证酸洗作业计划明细记录存在
		PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setPc_plan_no(psp.getPc_plan_no());
		pcpd.setObject_no_vt(psp.getObject_no_vt());
		pcpd.setObject_no(psp.getMaterial_no());
		int count2 = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n虚拟卷号："+psp.getObject_no_vt()+""
					+ "\n原料卷号："+psp.getMaterial_no()+"\n作业计划明细记录不存在！");
		}
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"原料卷虚拟物料信息不存在！");
		}
		//
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "mat_object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"出口卷虚拟物料信息不存在！");
		}
		//  --(3)、验证原料卷对应的酸洗主实绩存在，且为“未交工”状态
		MesPlmM mCross = new MesPlmM();
		mCross.setMachine_code(sum.getMemo1());
		mCross.setSchedule_no(psp.getPc_plan_no());
		mCross.setMaterial_no_vt(psp.getObject_no_vt());
		mCross.setMaterial_no(psp.getMaterial_no());
		v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
		if (v_cnt<=0) {
			r.setState("500");
			r.setMsgInfo("原料卷号：" +psp.getMaterial_no()+ "，当前不存在酸洗作业实绩！请确认是否已操作上料！");
			return r;
		}
	    List<MesPlmM> lmcam = this.getMapper(MesPlmMMapper.class).find(mCross, 0, 0);
	    MesPlmM v_rec_Rcm =lmcam.get(0);
	    if(v_rec_Rcm.getHand_over_status()!=null && !v_rec_Rcm.getHand_over_status().equals("0")){
	    	r.setState("500");
	    	r.setMsgInfo("原料卷号："+psp.getMaterial_no()+"当前已生产交工，不能重复操作！");
			return r;
	    }
	    
		//******  物料出库 ******
		//调用物流模块（仓库管理）接口，对原料卷进行生产投料出库操作（接口由物流模块提供）；																																							
		YdmProductDetail ypdu=new YdmProductDetail();
		ypdu.setCoilno(v_rec_Rcm.getMaterial_no());
		// 传入操作时间字符串带毫秒
		ypdu.setMemo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(now));
		CommonPage<YdmProductDetail> ypdCp=new CommonPage<YdmProductDetail>();
		ypdCp.setObject(ypdu);
		this.getBean(LmsApiServiceImpl.class).doOutStorage(ypdCp);
		
	    // 6.、验证原料卷，当前已有出口卷实绩
		MesPlmD mcccd=new MesPlmD();
		mcccd.setProcess_no(v_rec_Rcm.getProcess_no());
		List<MesPlmD> lmcsd =this.getMapper(MesPlmDMapper.class).findWithCondition(mcccd,"coil_no not like '%B'", " coil_no ", 0, 0);
		if(lmcsd==null||lmcsd.size()==0){
			throw new Exception("作业计划原料卷不存在出口卷实绩!");
		}
	    
	    PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setMat_object_no_vt(psp.getObject_no_vt());
		List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(pmd, "", " serial_no ", 0, 0);
		int k=0,n=lpmd.size()-1;
		// 逐一循环出口卷实绩（废副品物料除外），验证各出口卷的 厚、宽、长、实重 都＞0
		List<MesPlmD> listD=	this.getMapper(MesPlmDMapper.class).FindMescrcrDByprocessNo(v_rec_Rcm.getProcess_no());
		for (MesPlmD  cur_01 : listD) {
			if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
				throw new Exception("出口卷:"+cur_01.getCoil_no()+"厚度必须大于0！");
			}
			if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
				throw new Exception("出口卷:"+cur_01.getCoil_no()+"宽度必须大于0！");
			}
			//if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
				//throw new Exception("出口卷:"+cur_01.getCoil_no()+"长度必须大于0！");
			//}
			if(cur_01.getCoil_act_wgt()==null||cur_01.getCoil_act_wgt()<=0){
				throw new Exception("出口卷["+cur_01.getCoil_no()+"]重量需大于0");
			}
			//调用物流模块（仓库管理）接口，验证产生的吊销卷号 在库存信息中不存在
			YdmProductDetail ypd=new YdmProductDetail();
			ypd.setCoilno(cur_01.getCoil_no());
			List<YdmProductDetail> lypd=this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
			if(lypd!=null&&lypd.size()>0){
				throw new Exception("钢卷号唯一，不能重复");
			}

			//---------------2018-03-15----------------------
			if(k<=n){
				MesPlmD mcd=new MesPlmD();
				mcd.setCoil_no(cur_01.getCoil_no());
				mcd.setCoil_no_vt(lpmd.get(k).getObject_no_vt());
				mcd.setOrder_no(lpmd.get(k).getOrder_no());
				mcd.setProd_order_no(lpmd.get(k).getProd_order_no());
				this.getMapper(MesPlmDMapper.class).update(mcd);
			}
			k++;			
		}
  		
		//班组班次调整 (取交工的登录班次班组)	20200102
  		MesPlmM mmm=new MesPlmM();
  		mmm.setProcess_no(v_rec_Rcm.getProcess_no());
  		mmm.setWrk_grp(work_grp);
  		mmm.setWrk_ord(work_ord);
  		mmm.setWrk_date(work_date);
  		this.getMapper(MesPlmMMapper.class).update(mmm);
  		
  		//更新子表班组(取交工的登录班次班组)	20200102
  		MesPlmD mdd=new MesPlmD();
  		mdd.setProcess_no(v_rec_Rcm.getProcess_no());
  		List<MesPlmD> lmddq=this.getMapper(MesPlmDMapper.class).findWithCondition(mdd, "", " coil_no ", 0, 0);
  		for(MesPlmD mc : lmddq){
  			MesPlmD mcsd=new MesPlmD();
  			mcsd.setCoil_no(mc.getCoil_no());
  			mcsd.setWrk_grp(work_grp);
  			mcsd.setWrk_ord(work_ord);
  			mcsd.setWrk_date(work_date);
  			this.getMapper(MesPlmDMapper.class).update(mcsd);
  		}  		
	    	    
	    try{  	
	    	//2019-02-21
		  		/*
		  		检验批分批规则：
		  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
		  		 */
			    Map<String, List<MesPlmD>> mc_list =new HashMap<String, List<MesPlmD>>();
		  		if(v_rec_Rcm.getSchedule_no()!=null && !"".equals(v_rec_Rcm.getSchedule_no())){
		  			List<MesPlmM> v_rec_baf_mList = this.getMapper(MesPlmMMapper.class).findWithCondition(null,"schedule_no='"+v_rec_Rcm.getSchedule_no()+"'", null, 0, 0);
		  			List<MesPlmD> mcdlist=new ArrayList<MesPlmD>();
		  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
	  					try{
	  						mc_list = groupBillingDataByExcpBatchCode(mcdlist,v_rec_Rcm.getSchedule_no());
	  					}catch(Exception e){
	  						
	  					}
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesPlmD>> grouplist :mc_list.entrySet()){
						List<MesPlmD> listCes = grouplist.getValue();
						for(MesPlmD mcam:listCes){
								MesPlmD mCrossleo = new MesPlmD();
								//mCrossleo.setMachine_code(sum.getMemo1());
								mCrossleo.setCoil_no(mcam.getCoil_no());
								mCrossleo.setInspection_lot(mcam.getInspection_lot());
								this.getMapper(MesPlmDMapper.class).update(mCrossleo);
						}
					}
				}
	    	
	    }catch(Exception e){
	    	
	    }
	    
	    
	    //循环酸洗出口卷实绩（MES_CR_SLITTING_D，此时，出口卷已完成匹配虚拟出口卷号，需要重新获取出口卷实绩集合
	    MesPlmD mc=new MesPlmD();
	    mc.setProcess_no(v_rec_Rcm.getProcess_no());
	  	List<MesPlmD> lmcsq=this.getMapper(MesPlmDMapper.class).find(mc, 0, 0);
	  	for(MesPlmD mcsq:lmcsq){	  			
			//  2018-6-21 将下面注解的东西修改成上面的
			if (mcsq.getCoil_no() !=null && "B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))) {
				if (mcsq.getCoil_act_wgt()==null || mcsq.getCoil_act_wgt().intValue()<=0) {
					continue;
				}
			}
			if(mcsq.getCoil_act_wgt()==null || mcsq.getCoil_act_wgt().intValue()<=0){
				throw new Exception("出口卷["+mcsq.getCoil_no()+"]实重异常！");
			}
	  			
  			CommonPage<MesPlmD> cp=new CommonPage<MesPlmD>();
  			MesPlmD mcsd=new MesPlmD();
  			mcsd.setCoil_no(mcsq.getCoil_no());
  			mcsd.setCoil_no_vt(mcsq.getCoil_no_vt());
  			cp.setObject(mcsq);
  			//调用物流模块（仓库管理）接口，逐一将酸洗出口卷实绩各出口卷，插入库存记录（待入库状态）；	
  			try{
  				//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
  				/**
  				 *  MesApiDesignInfoImpl/getNextProcessCode
  					 code 当前工序代码 1 酸洗/2 开平/3 罩退/4 酸洗
  					 object_no_vt 虚拟物料号
  					如果下一个工序不存在 则返回 ""
  				 */
  				String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("6", psp.getObject_no_vt());
  				nextP = nextProcessCode;
  				if(nextProcessCode==null || "".equals(nextProcessCode)){
  					cp.setMemo1("500203");//成品库
  					// 酸洗交工这里之前没有写入生产订单的已生产量：所以得补上20230908 刘侣
  					//生产订单统计 统计量并修改生产订单状态
  				    try{
//  				    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(mcsq.getCoil_no(),1,true);
  				    }catch(Exception e){
  				    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
  				    	e.printStackTrace();
  				    }
  				}else{
  					cp.setMemo1("500202");//在制品库
  				}
  				ResultModel rm = this.getBean(LmsMesApiServiceImpl.class).doInsertMesPlm(cp);
  				if ("200".equals(rm.getState())) {
  					//成功
  					// 这里才插入，那就得这里才进行
  					
  					// 写入库存表后去更新生产订单状态：20230909刘侣；
  					YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(mcsq.getCoil_no(), null);
  					if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
  						this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,true);
  						
  					}
  				
  				// 检验委托：如果是最后一道工序才需要送样，去做检验委托：
  					// 待判信息发送：如果是最后一道工序（进成品库），那么就给isfinal ： 1， 否则就是：0；
  					if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
  						
  						// 发送检验委托信息：20230909刘侣：最后一道工序才送样
  						if (mcsq.getCoil_no() != null && ("B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))
  								 || "H".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1)))) {
  							
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), true, "1");
  						} else {
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), false, "1");
  						}
  						// 只有以6开头的订单才去发送检验委托：
  						if (ypdQ.getOrderno() != null) {
  							ResultModel rmwt = this.getBean(SlmFundFirstDetailServiceImpl.class).sendToJYWT(mcsq.getCoil_no(), true);
  	  						if ("500".equals(rmwt.getState())) {
  	  							throw new Exception(rmwt.getMsgInfo());
  	  						}
  						}
  						// end
  					} else {
  						// 非最后一道：
  						if (mcsq.getCoil_no() != null && ("B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))
  								 || "H".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1)))) {
  							
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), true, "0");
  						} else {
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), false, "0");
  						}
  					}
  					// end
  					// end
  					
  				}else {
  					//失败
  					throw new Exception("入库出错"+rm.getMsgInfo());//失败原因，信息或提示
  				}
  			}catch(Exception ex){
  				ex.printStackTrace();
  				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(mcsq.getCoil_no(),mcsq.getProd_order_no(),processpoint.pickle_code);
			} catch(Exception ex) {
				// 暂时先注释：2019101 刘侣
//				throw new Exception("获取质量判定信息接口报错!"+ ex.getMessage());
			}
			if(!"200".equals(tmp_rst.getState())){
				// 暂时先注释：2019101 刘侣
//				throw new Exception(tmp_rst.getData().toString());
			}
				
  			try{
				ResultModel rmxx = this.getBean(QmsApiServiceImpl.class).doQueryJudegeResult(mcsq.getCoil_no());
				if(rmxx!=null && rmxx.getData()!=null && (rmxx.getData() instanceof JudgeResult)){
					JudgeResult jr=(JudgeResult)rmxx.getData();
					YdmProductDetail ypd=new YdmProductDetail();
					ypd.setCoilno(mcsq.getCoil_no());
					ypd.setMarginal_result(jr.getMarginal_result());
					ypd.setMarginal_result_id(jr.getMarginal_result_id());
					ypd.setMeasure_result(jr.getMeasure_result());
					ypd.setMeasure_result_id(jr.getMeasure_result_id());
					ypd.setSfd_is_lock(jr.getSfd_is_lock());
					ypd.setSfe_is_lock(jr.getSfe_is_lock());
					ypd.setSic_is_lock(jr.getSic_is_lock());
					ypd.setSfu_is_lock(jr.getSfu_is_lock());
					ypd.setSizeresult(jr.getSizeResult());
					ypd.setUd_surface_result(jr.getUd_surface_result());
					ypd.setUd_surface_result_id(jr.getUd_surface_result_id());
					ypd.setUp_surface_flaw(jr.getUp_surface_flaw());
					ypd.setUp_surface_result(jr.getUp_surface_result());
					ypd.setUp_surface_result_id(jr.getUp_surface_result_id());
					ypd.setUd_surface_flaw(jr.getUd_surface_flaw());
					ypd.setMarginal_flaw(jr.getMarginal_flaw());
//					this.getMapper(YdmProductDetailMapper.class).update(ypd);
				}
			}catch(Exception e){
				System.out.println("调用质量接口报错");
				e.printStackTrace();
			}
	  			
  			//循环酸洗出口卷实绩（MES_CR_SLITTING_D，此时，出口卷已完成匹配虚拟出口卷号，需要重新获取出口卷实绩集合
  			//如果此出口卷的虚拟出口卷号不为空（COIL_NO_VT，即满足切割计划）
  			if(mcsq.getCoil_no_vt()!=null && !"".equals(mcsq.getCoil_no_vt())){
  				//  --(2.10)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；
  			    // 处理出口卷
  				List<PlnMaterielDetail> lpmdc=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_Rcm.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
  				if (Utils.isEmpty(lpmdc)) {
  					throw new Exception("未找到虚拟出口卷信息!");
  				}
  				PlnMaterielDetail pmdq=new PlnMaterielDetail();
  				pmdq.setObject_no(v_rec_Rcm.getMaterial_no());
  				pmdq.setObject_no_vt(mcsq.getCoil_no_vt());
  				pmdq.setMaterial_no(v_rec_Rcm.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
  				pmdq.setSub_object_no(mcsq.getCoil_no()); // 出口卷号
  				// 传入操作时间 2018-06-19
  				pmdq.setCreate_time(now);
  				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_Relation(pmdq);
  				
  			}else if (mcsq.getCoil_no() != null && "B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))){
	  				//则调用生产管理的【酸洗完成——实物 生成接口】 2018-06-22
  				PrcMaterielRelation pmr=new PrcMaterielRelation();
  				pmr.setObject_no(psp.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
  				pmr.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
  				pmr.setRelation_seq(3);
  				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_PrcMatRelAdd(pmr);//有insert插入prc_materiel_relation的操作
  			}else{//如果此出口卷的虚拟出口卷号为空（COIL_NO_VT，即为非计划）
	  				//则调用生产管理的【酸洗完成——实物 生成接口】
  				//第二卷
				PlnMaterielDetail pmdq2=new PlnMaterielDetail();
				pmdq2.setObject_no(v_rec_Rcm.getMaterial_no());
				pmdq2.setMaterial_no(v_rec_Rcm.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmdq2.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
				// 传入操作时间 2018-06-22
				pmdq2.setCreate_time(now);
				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_No_Plan(pmdq2);//有insert插入PLN_MATERIEL_DETAIL的操作
  				
  			}
	  			
	  			//===============2019-03-12========质量检验委托开始=============================
	  		    if(v_rec_Rcm.getSchedule_no()!=null && !"".equals(v_rec_Rcm.getSchedule_no())){//作业计划号不为空
	  		    	try{
	  		    		QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
						List<PlnMaterielDetail> lpmdq22 = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
								"object_no_vt = '" + v_rec_Rcm.getMaterial_no_vt() + "' and nvl(invalid_flg,0) = '0'", null, 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(v_rec_Rcm.getMaterial_no_vt(), "A");
							// 获取工艺路径包含成分或者材质类
							if(judge_Contain_Qcm!=-1){
								ajsfp.setPline_seq((long)judge_Contain_Qcm);
	  					  	ajsfp.setInspection_lot(mcsq.getInspection_lot());//检验号
		  					  	ajsfp.setBatch_no(v_rec_Rcm.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.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
								ajsfp.setMaterial_no(mcsq.getCoil_no());//取样材料号   
								ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
								ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
								ajsfp.setBoard_no(v_rec_Rcm.getMaterial_no());
								
								ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_Rcm.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("A");//工序代码    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);
								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();
	  				}
	  		    }
	  			//==========================质量检验委托结束==================================
	  			
	  		}
		
		// 处理母卷
		List<PlnMaterielDetail> lpmdq = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + v_rec_Rcm.getMaterial_no_vt() + "' and nvl(invalid_flg,0) = '0'", null, 0, 1);
		this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_Sum(lpmdq.get(0));
		
	    //  --(2.11)、修改酸洗作业主实绩交工状态
	    MesPlmM mes=new MesPlmM();
	    mes.setHand_over_status("1");
	    mes.setHand_over_time(now);
	    mes.setHand_over_opr(username);
	    mes.setUpdate_opr(username);
	    mes.setUpdate_time(now);
	    mes.setMachine_code(sum.getMemo1());
	    mes.setSchedule_no(psp.getPc_plan_no());
	    mes.setMaterial_no_vt(psp.getObject_no_vt());
	    mes.setMaterial_no(psp.getMaterial_no());
	    mes.setProcess_no(v_rec_Rcm.getProcess_no());
	    this.getMapper(MesPlmMMapper.class).doUpdate2(mes);
	    
	    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
		if ("1".equals(isOpen)) {
		
		    // 记录成本异动点：20230811刘侣
		    YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(psp.getMaterial_no());
	 		ComBaseCbYdd cd = new ComBaseCbYdd();
	 		cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
	 		cd.setInstDisp("01");
	 		cd.setDataTypeIdx("O");
	 		// 当前产线：
	 		String currentMachine = ypdM.getCoilno().contains("S") ? "YTSX" : ypdM.getCoilno().contains("L") ? "YTZZ" : ypdM.getCoilno().contains("P") ? "YTPZ" : ypdM.getCoilno().contains("T") ? "YTTH" : ypdM.getCoilno().contains("K") ? "YTHJ" : ypdM.getCoilno().contains("F") ? "YTZJ" : "YT1";
	 		cd.setLocNo(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setInvQtyUnit("块");
	 		cd.setInvWidth(ypdM.getWidth() != null ? String.valueOf(ypdM.getWidth()) : "0");
	 		cd.setCreateId(userId);
	 		cd.setActivityId("41A");
	 		cd.setInvLength(ypdM.getLength() != null ? String.valueOf(ypdM.getLength()) : "0");
	 		cd.setManageip(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setProdName(ypdM.getProd_name());
	 		cd.setInvThick(ypdM.getThick() != null ? String.valueOf(ypdM.getThick()) : "0");
	 		
	 		
	 		String prevcoil = ypdM.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) ? ypdM.getMaterailcoilno() : prevcoil); // 投料卷号
	 		cd.setSysId("IA");
	 		cd.setOrderItem(ypdM.getOrderno());
	 		cd.setCrntMill(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setBeTransUnit("t");
	 		cd.setExecJobFunc("N");
	 		ComBaseSteel cbs = this.getMapper(ComBaseSteelMapper.class).findById(ypdM.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(ypdM.getFactweight() != null ? ypdM.getFactweight() / 1000 : ypdM.getFactweight());
	 		cd.setProdTypeNo("CTR");
	 		cd.setAppId("优特钢酸洗上料");
	 		cd.setInvId("YT1".equals(currentMachine) ? ypdM.getMaterailcoilno() : ypdM.getCoilno());
	 		cd.setInvQty("1");

			// setSrcFac根据卷的物料属性去判断：20231031刘侣
			cd.setSrcFac("507101".equals(ypdM.getObject_attr()) ? "1" : "3");
			
	 		cd.setGrade("40740801".equals(ypdM.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 = ypdM.getCoilno().contains("S") ? "酸洗" : ypdM.getCoilno().contains("L") ? "冷轧" : ypdM.getCoilno().contains("P") ? "平整" : ypdM.getCoilno().contains("T") ? "退火" : ypdM.getCoilno().contains("K") ? "横剪" : ypdM.getCoilno().contains("F") ? "分条" : "原料";
			String prevMName = prevcoil.contains("S") ? "酸洗" : prevcoil.contains("L") ? "冷轧" : prevcoil.contains("P") ? "平整" : prevcoil.contains("T") ? "退火" : prevcoil.contains("K") ? "开平" : prevcoil.contains("F") ? "分条" : "原料";
			// 原料转库，2、酸洗接收原料，3、酸洗上料
			cd.setAppId("优特" + prevMName + "转库");
			
			// 一次结算后第一次生产点上料的时候，不抛 转库和接收原料  改抛 12AB
			// 该卷是否刚刚一次结算完：可以根据提单里是否有这卷的一次结算数据进行判断：
//			int isYcJs = this.getMapper(YdmProductDetailMapper.class).isHasYcJs(ypdM.getCoilno());
//			if (isYcJs <= 0) {
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
//			}
			
			// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
			// 对已有数据进行修改：
			cd.setDataTypeIdx("N");
//			cd.setProdTypeNo("CTR");
			cd.setManageip("YTSX");
			cd.setLocNo("YTSX");
			cd.setAppId("优特酸洗接收原料");
			
			// 20231130刘侣
//			if (isYcJs > 0) {
//				cd.setActivityId("12AB");
//				cd.setAppId("来料加工");
//			}
			// end
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// 三抛：酸洗上料（41，开始生产
			cd.setActivityId("41A");
			cd.setDataTypeIdx("O");
			cd.setAppId("优特酸洗上料");
			cd.setLastMill("YTSX");
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// end
		}
	    
	    
	    //日志
	    MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "交工", username, opr_time, mes.getMaterial_no(), null, null, null, "投料卷号："+mes.getMaterial_no() + "；下道工序为：" + nextP);
	    this.getMapper(MesOprLogMapper.class).insert(mol);
	    
	    //  --(3)、提交事务
		r.setState("200");
		r.setMsgInfo("交工成功!");
		return r;
	}
	
	
	
	/***
	 * 动作处理--交工按钮   
	 * object中：
	 * Pc_plan_no 作业计划号【酸洗计划号】
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOffNew(CommonPage<PlnPicklePlan> sum) throws Exception {
		ResultModel r=new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String userId = (String) this.getSession().getAttribute(HomeService.SESSION_USER_ID);
		String username = (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);
		PlnPicklePlan psp = sum.getObject();
		
		String nextP = "";
		
		Integer v_cnt;
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		if("".equals(psp.getPc_plan_no()) || "".equals(psp.getPc_plan_no())){
			r.setState("500");
			r.setMsgInfo("参数错误：作业计划号为空");
			return r;
		}		
		// --(1)、验证酸洗作业计划主记录存在
		PlnPicklePlan pcp=new PlnPicklePlan();
		pcp.setMachine_code(sum.getMemo1());
		pcp.setPc_plan_no(psp.getPc_plan_no());
		int count = this.getMapper(PlnPicklePlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n作业计划主记录不存在！");
		}
		//    --(2.2)、验证酸洗作业计划明细记录存在
		PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setPc_plan_no(psp.getPc_plan_no());
		pcpd.setObject_no_vt(psp.getObject_no_vt());
		pcpd.setObject_no(psp.getMaterial_no());
		int count2 = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n虚拟卷号："+psp.getObject_no_vt()+""
					+ "\n原料卷号："+psp.getMaterial_no()+"\n作业计划明细记录不存在！");
		}
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"原料卷虚拟物料信息不存在！");
		}
		//
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "mat_object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"出口卷虚拟物料信息不存在！");
		}
		//  --(3)、验证原料卷对应的酸洗主实绩存在，且为“未交工”状态
		MesPlmM mCross = new MesPlmM();
		mCross.setMachine_code(sum.getMemo1());
		mCross.setSchedule_no(psp.getPc_plan_no());
		mCross.setMaterial_no_vt(psp.getObject_no_vt());
		mCross.setMaterial_no(psp.getMaterial_no());
		v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
		if (v_cnt<=0) {
			r.setState("500");
			r.setMsgInfo("原料卷号：" +psp.getMaterial_no()+ "，当前不存在酸洗作业实绩！请确认是否已操作上料！");
			return r;
		}
	    List<MesPlmM> lmcam = this.getMapper(MesPlmMMapper.class).find(mCross, 0, 0);
	    MesPlmM v_rec_Rcm =lmcam.get(0);
	    if(v_rec_Rcm.getHand_over_status()!=null && !v_rec_Rcm.getHand_over_status().equals("0")){
	    	r.setState("500");
	    	r.setMsgInfo("原料卷号："+psp.getMaterial_no()+"当前已生产交工，不能重复操作！");
			return r;
	    }
	    
		//******  物料出库 ******
		//调用物流模块（仓库管理）接口，对原料卷进行生产投料出库操作（接口由物流模块提供）；																																							
		YdmProductDetail ypdu=new YdmProductDetail();
		ypdu.setCoilno(v_rec_Rcm.getMaterial_no());
		// 传入操作时间字符串带毫秒
		ypdu.setMemo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(now));
		CommonPage<YdmProductDetail> ypdCp=new CommonPage<YdmProductDetail>();
		ypdCp.setObject(ypdu);
		this.getBean(LmsApiServiceImpl.class).doOutStorage(ypdCp);
		
	    // 6.、验证原料卷，当前已有出口卷实绩
		MesPlmD mcccd=new MesPlmD();
		mcccd.setProcess_no(v_rec_Rcm.getProcess_no());
		List<MesPlmD> lmcsd =this.getMapper(MesPlmDMapper.class).findWithCondition(mcccd,"coil_no not like '%B'", " coil_no ", 0, 0);
		if(lmcsd==null||lmcsd.size()==0){
			throw new Exception("作业计划原料卷不存在出口卷实绩!");
		}
	    
	    PlnMaterielDetail pmd=new PlnMaterielDetail();
		pmd.setMat_object_no_vt(psp.getObject_no_vt());
		List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(pmd, "", " serial_no ", 0, 0);
		int k=0,n=lpmd.size()-1;
		// 逐一循环出口卷实绩（废副品物料除外），验证各出口卷的 厚、宽、长、实重 都＞0
		List<MesPlmD> listD=	this.getMapper(MesPlmDMapper.class).FindMescrcrDByprocessNo(v_rec_Rcm.getProcess_no());
		for (MesPlmD  cur_01 : listD) {
			if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
				throw new Exception("出口卷:"+cur_01.getCoil_no()+"厚度必须大于0！");
			}
			if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
				throw new Exception("出口卷:"+cur_01.getCoil_no()+"宽度必须大于0！");
			}
			//if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
				//throw new Exception("出口卷:"+cur_01.getCoil_no()+"长度必须大于0！");
			//}
			if(cur_01.getCoil_act_wgt()==null||cur_01.getCoil_act_wgt()<=0){
				throw new Exception("出口卷["+cur_01.getCoil_no()+"]重量需大于0");
			}
			//调用物流模块（仓库管理）接口，验证产生的吊销卷号 在库存信息中不存在
			YdmProductDetail ypd=new YdmProductDetail();
			ypd.setCoilno(cur_01.getCoil_no());
			List<YdmProductDetail> lypd=this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
			if(lypd!=null&&lypd.size()>0){
				throw new Exception("钢卷号唯一，不能重复");
			}

			//---------------2018-03-15----------------------
			if(k<=n){
				MesPlmD mcd=new MesPlmD();
				mcd.setCoil_no(cur_01.getCoil_no());
				mcd.setCoil_no_vt(lpmd.get(k).getObject_no_vt());
				mcd.setOrder_no(lpmd.get(k).getOrder_no());
				mcd.setProd_order_no(lpmd.get(k).getProd_order_no());
				this.getMapper(MesPlmDMapper.class).update(mcd);
			}
			k++;			
		}
  		
		//班组班次调整 (取交工的登录班次班组)	20200102
  		MesPlmM mmm=new MesPlmM();
  		mmm.setProcess_no(v_rec_Rcm.getProcess_no());
  		mmm.setWrk_grp(work_grp);
  		mmm.setWrk_ord(work_ord);
  		mmm.setWrk_date(work_date);
  		this.getMapper(MesPlmMMapper.class).update(mmm);
  		
  		//更新子表班组(取交工的登录班次班组)	20200102
  		MesPlmD mdd=new MesPlmD();
  		mdd.setProcess_no(v_rec_Rcm.getProcess_no());
  		List<MesPlmD> lmddq=this.getMapper(MesPlmDMapper.class).findWithCondition(mdd, "", " coil_no ", 0, 0);
  		for(MesPlmD mc : lmddq){
  			MesPlmD mcsd=new MesPlmD();
  			mcsd.setCoil_no(mc.getCoil_no());
  			mcsd.setWrk_grp(work_grp);
  			mcsd.setWrk_ord(work_ord);
  			mcsd.setWrk_date(work_date);
  			this.getMapper(MesPlmDMapper.class).update(mcsd);
  		}  		
	    	    
	    try{  	
	    	//2019-02-21
		  		/*
		  		检验批分批规则：
		  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
		  		 */
			    Map<String, List<MesPlmD>> mc_list =new HashMap<String, List<MesPlmD>>();
		  		if(v_rec_Rcm.getSchedule_no()!=null && !"".equals(v_rec_Rcm.getSchedule_no())){
		  			List<MesPlmM> v_rec_baf_mList = this.getMapper(MesPlmMMapper.class).findWithCondition(null,"schedule_no='"+v_rec_Rcm.getSchedule_no()+"'", null, 0, 0);
		  			List<MesPlmD> mcdlist=new ArrayList<MesPlmD>();
		  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
	  					try{
	  						mc_list = groupBillingDataByExcpBatchCode(mcdlist,v_rec_Rcm.getSchedule_no());
	  					}catch(Exception e){
	  						
	  					}
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesPlmD>> grouplist :mc_list.entrySet()){
						List<MesPlmD> listCes = grouplist.getValue();
						for(MesPlmD mcam:listCes){
								MesPlmD mCrossleo = new MesPlmD();
								//mCrossleo.setMachine_code(sum.getMemo1());
								mCrossleo.setCoil_no(mcam.getCoil_no());
								mCrossleo.setInspection_lot(mcam.getInspection_lot());
								this.getMapper(MesPlmDMapper.class).update(mCrossleo);
						}
					}
				}
	    	
	    }catch(Exception e){
	    	
	    }
	    
	    
	    //循环酸洗出口卷实绩（MES_CR_SLITTING_D，此时，出口卷已完成匹配虚拟出口卷号，需要重新获取出口卷实绩集合
	    MesPlmD mc=new MesPlmD();
	    mc.setProcess_no(v_rec_Rcm.getProcess_no());
	  	List<MesPlmD> lmcsq=this.getMapper(MesPlmDMapper.class).find(mc, 0, 0);
	  	for(MesPlmD mcsq:lmcsq){	  			
			//  2018-6-21 将下面注解的东西修改成上面的
			if (mcsq.getCoil_no() !=null && "B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))) {
				if (mcsq.getCoil_act_wgt()==null || mcsq.getCoil_act_wgt().intValue()<=0) {
					continue;
				}
			}
			if(mcsq.getCoil_act_wgt()==null || mcsq.getCoil_act_wgt().intValue()<=0){
				throw new Exception("出口卷["+mcsq.getCoil_no()+"]实重异常！");
			}
	  			
  			CommonPage<MesPlmD> cp=new CommonPage<MesPlmD>();
  			MesPlmD mcsd=new MesPlmD();
  			mcsd.setCoil_no(mcsq.getCoil_no());
  			mcsd.setCoil_no_vt(mcsq.getCoil_no_vt());
  			cp.setObject(mcsq);
  			//调用物流模块（仓库管理）接口，逐一将酸洗出口卷实绩各出口卷，插入库存记录（待入库状态）；	
  			try{
  				//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
  				/**
  				 *  MesApiDesignInfoImpl/getNextProcessCode
  					 code 当前工序代码 1 酸洗/2 开平/3 罩退/4 酸洗
  					 object_no_vt 虚拟物料号
  					如果下一个工序不存在 则返回 ""
  				 */
  				String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("6", psp.getObject_no_vt());
  				nextP = nextProcessCode;
  				if(nextProcessCode==null || "".equals(nextProcessCode)){
  					cp.setMemo1("500203");//成品库
  					// 酸洗交工这里之前没有写入生产订单的已生产量：所以得补上20230908 刘侣
  					//生产订单统计 统计量并修改生产订单状态
  				    try{
//  				    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(mcsq.getCoil_no(),1,true);
  				    }catch(Exception e){
  				    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
  				    	e.printStackTrace();
  				    }
  				}else{
  					cp.setMemo1("500202");//在制品库
  				}
  				ResultModel rm = this.getBean(LmsMesApiServiceImpl.class).doInsertMesPlm(cp);
  				if ("200".equals(rm.getState())) {
  					//成功
  					// 这里才插入，那就得这里才进行
  					
  					// 写入库存表后去更新生产订单状态：20230909刘侣；
  					YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(mcsq.getCoil_no(), null);
  					if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
  						this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,true);
  						
  					}
  				
  				// 检验委托：如果是最后一道工序才需要送样，去做检验委托：
  					// 待判信息发送：如果是最后一道工序（进成品库），那么就给isfinal ： 1， 否则就是：0；
  					if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
  						
  						// 发送检验委托信息：20230909刘侣：最后一道工序才送样
  						if (mcsq.getCoil_no() != null && ("B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))
  								 || "H".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1)))) {
  							
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), true, "1");
  						} else {
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), false, "1");
  						}
  						
  						// 只有以6开头的订单才去发送检验委托：
  						if (ypdQ.getOrderno() != null ) {
  							ResultModel rmwt = this.getBean(SlmFundFirstDetailServiceImpl.class).sendToJYWT(mcsq.getCoil_no(), true);
  	  						if ("500".equals(rmwt.getState())) {
  	  							throw new Exception(rmwt.getMsgInfo());
  	  						}
  						}
  						
  						// end
  					} else {
  						// 非最后一道：
  						if (mcsq.getCoil_no() != null && ("B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))
  								 || "H".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1)))) {
  							
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), true, "0");
  						} else {
  							this.getBean(SlmFundFirstDetailServiceImpl.class).sendToPD(mcsq.getCoil_no(), false, "0");
  						}
  					}
  					// end
  					// end
  					
  				}else {
  					//失败
  					throw new Exception("入库出错"+rm.getMsgInfo());//失败原因，信息或提示
  				}
  			}catch(Exception ex){
  				ex.printStackTrace();
  				throw new Exception("入库接口，"+ ex.getMessage());
  			}

  			// 新交工接口去掉质量判定校验：20230921刘侣
//			// 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(mcsq.getCoil_no(),mcsq.getProd_order_no(),processpoint.pickle_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(mcsq.getCoil_no());
//				if(rmxx!=null && rmxx.getData()!=null && (rmxx.getData() instanceof JudgeResult)){
//					JudgeResult jr=(JudgeResult)rmxx.getData();
//					YdmProductDetail ypd=new YdmProductDetail();
//					ypd.setCoilno(mcsq.getCoil_no());
//					ypd.setMarginal_result(jr.getMarginal_result());
//					ypd.setMarginal_result_id(jr.getMarginal_result_id());
//					ypd.setMeasure_result(jr.getMeasure_result());
//					ypd.setMeasure_result_id(jr.getMeasure_result_id());
//					ypd.setSfd_is_lock(jr.getSfd_is_lock());
//					ypd.setSfe_is_lock(jr.getSfe_is_lock());
//					ypd.setSic_is_lock(jr.getSic_is_lock());
//					ypd.setSfu_is_lock(jr.getSfu_is_lock());
//					ypd.setSizeresult(jr.getSizeResult());
//					ypd.setUd_surface_result(jr.getUd_surface_result());
//					ypd.setUd_surface_result_id(jr.getUd_surface_result_id());
//					ypd.setUp_surface_flaw(jr.getUp_surface_flaw());
//					ypd.setUp_surface_result(jr.getUp_surface_result());
//					ypd.setUp_surface_result_id(jr.getUp_surface_result_id());
//					ypd.setUd_surface_flaw(jr.getUd_surface_flaw());
//					ypd.setMarginal_flaw(jr.getMarginal_flaw());
//					this.getMapper(YdmProductDetailMapper.class).update(ypd);
//				}
//			}catch(Exception e){
//				System.out.println("调用质量接口报错");
//				e.printStackTrace();
//			}
	  			
  			//循环酸洗出口卷实绩（MES_CR_SLITTING_D，此时，出口卷已完成匹配虚拟出口卷号，需要重新获取出口卷实绩集合
  			//如果此出口卷的虚拟出口卷号不为空（COIL_NO_VT，即满足切割计划）
  			if(mcsq.getCoil_no_vt()!=null && !"".equals(mcsq.getCoil_no_vt())){
  				//  --(2.10)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；
  			    // 处理出口卷
  				List<PlnMaterielDetail> lpmdc=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_Rcm.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
  				if (Utils.isEmpty(lpmdc)) {
  					throw new Exception("未找到虚拟出口卷信息!");
  				}
  				PlnMaterielDetail pmdq=new PlnMaterielDetail();
  				pmdq.setObject_no(v_rec_Rcm.getMaterial_no());
  				pmdq.setObject_no_vt(mcsq.getCoil_no_vt());
  				pmdq.setMaterial_no(v_rec_Rcm.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
  				pmdq.setSub_object_no(mcsq.getCoil_no()); // 出口卷号
  				// 传入操作时间 2018-06-19
  				pmdq.setCreate_time(now);
  				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_Relation(pmdq);
  				
  			}else if (mcsq.getCoil_no() != null && "B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))){
	  				//则调用生产管理的【酸洗完成——实物 生成接口】 2018-06-22
  				PrcMaterielRelation pmr=new PrcMaterielRelation();
  				pmr.setObject_no(psp.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
  				pmr.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
  				pmr.setRelation_seq(3);
  				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_PrcMatRelAdd(pmr);//有insert插入prc_materiel_relation的操作
  			}else{//如果此出口卷的虚拟出口卷号为空（COIL_NO_VT，即为非计划）
	  				//则调用生产管理的【酸洗完成——实物 生成接口】
  				//第二卷
				PlnMaterielDetail pmdq2=new PlnMaterielDetail();
				pmdq2.setObject_no(v_rec_Rcm.getMaterial_no());
				pmdq2.setMaterial_no(v_rec_Rcm.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmdq2.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
				// 传入操作时间 2018-06-22
				pmdq2.setCreate_time(now);
				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_No_Plan(pmdq2);//有insert插入PLN_MATERIEL_DETAIL的操作
  				
  			}
	  			
//	  			//===============2019-03-12========质量检验委托开始=============================
//	  		    if(v_rec_Rcm.getSchedule_no()!=null && !"".equals(v_rec_Rcm.getSchedule_no())){//作业计划号不为空
//	  		    	try{
//	  		    		QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
//						List<PlnMaterielDetail> lpmdq22 = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
//								"object_no_vt = '" + v_rec_Rcm.getMaterial_no_vt() + "' and nvl(invalid_flg,0) = '0'", null, 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(v_rec_Rcm.getMaterial_no_vt(), "A");
//							// 获取工艺路径包含成分或者材质类
//							if(judge_Contain_Qcm!=-1){
//								ajsfp.setPline_seq((long)judge_Contain_Qcm);
//	  					  	ajsfp.setInspection_lot(mcsq.getInspection_lot());//检验号
//		  					  	ajsfp.setBatch_no(v_rec_Rcm.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.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
//								ajsfp.setMaterial_no(mcsq.getCoil_no());//取样材料号   
//								ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
//								ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
//								ajsfp.setBoard_no(v_rec_Rcm.getMaterial_no());
//								
//								ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_Rcm.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("A");//工序代码    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);
//								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();
//	  				}
//	  		    }
	  			//==========================质量检验委托结束==================================
	  			
	  		}
		
		// 处理母卷
		List<PlnMaterielDetail> lpmdq = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
				"object_no_vt = '" + v_rec_Rcm.getMaterial_no_vt() + "' and nvl(invalid_flg,0) = '0'", null, 0, 1);
		this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_Sum(lpmdq.get(0));
		
	    //  --(2.11)、修改酸洗作业主实绩交工状态
	    MesPlmM mes=new MesPlmM();
	    mes.setHand_over_status("1");
	    mes.setHand_over_time(now);
	    mes.setHand_over_opr(username);
	    mes.setUpdate_opr(username);
	    mes.setUpdate_time(now);
	    mes.setMachine_code(sum.getMemo1());
	    mes.setSchedule_no(psp.getPc_plan_no());
	    mes.setMaterial_no_vt(psp.getObject_no_vt());
	    mes.setMaterial_no(psp.getMaterial_no());
	    mes.setProcess_no(v_rec_Rcm.getProcess_no());
	    this.getMapper(MesPlmMMapper.class).doUpdate2(mes);
	    
	    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
		if ("1".equals(isOpen)) {
		
		    // 记录成本异动点：20230811刘侣
		    YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(psp.getMaterial_no());
	 		ComBaseCbYdd cd = new ComBaseCbYdd();
	 		cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
	 		cd.setInstDisp("01");
	 		cd.setDataTypeIdx("O");
	 		// 当前产线：
	 		String currentMachine = ypdM.getCoilno().contains("S") ? "YTSX" : ypdM.getCoilno().contains("L") ? "YTZZ" : ypdM.getCoilno().contains("P") ? "YTPZ" : ypdM.getCoilno().contains("T") ? "YTTH" : ypdM.getCoilno().contains("K") ? "YTHJ" : ypdM.getCoilno().contains("F") ? "YTZJ" : "YT1";
	 		cd.setLocNo(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setInvQtyUnit("块");
	 		cd.setInvWidth(ypdM.getWidth() != null ? String.valueOf(ypdM.getWidth()) : "0");
	 		cd.setCreateId(userId);
	 		cd.setActivityId("41A");
	 		cd.setInvLength(ypdM.getLength() != null ? String.valueOf(ypdM.getLength()) : "0");
	 		cd.setManageip(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setProdName(ypdM.getProd_name());
	 		cd.setInvThick(ypdM.getThick() != null ? String.valueOf(ypdM.getThick()) : "0");
	 		
	 		
	 		String prevcoil = ypdM.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) ? ypdM.getMaterailcoilno() : prevcoil); // 投料卷号
	 		cd.setSysId("IA");
	 		cd.setOrderItem(ypdM.getOrderno());
	 		cd.setCrntMill(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setBeTransUnit("t");
	 		cd.setExecJobFunc("N");
	 		ComBaseSteel cbs = this.getMapper(ComBaseSteelMapper.class).findById(ypdM.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(ypdM.getFactweight() != null ? ypdM.getFactweight() / 1000 : ypdM.getFactweight());
	 		cd.setProdTypeNo("CTR");
	 		cd.setAppId("优特钢酸洗上料");
	 		cd.setInvId("YT1".equals(currentMachine) ? ypdM.getMaterailcoilno() : ypdM.getCoilno());
	 		cd.setInvQty("1");

			// setSrcFac根据卷的物料属性去判断：20231031刘侣
			cd.setSrcFac("507101".equals(ypdM.getObject_attr()) ? "1" : "3");
			
	 		cd.setGrade("40740801".equals(ypdM.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 = ypdM.getCoilno().contains("S") ? "酸洗" : ypdM.getCoilno().contains("L") ? "冷轧" : ypdM.getCoilno().contains("P") ? "平整" : ypdM.getCoilno().contains("T") ? "退火" : ypdM.getCoilno().contains("K") ? "横剪" : ypdM.getCoilno().contains("F") ? "分条" : "原料";
			String prevMName = prevcoil.contains("S") ? "酸洗" : prevcoil.contains("L") ? "冷轧" : prevcoil.contains("P") ? "平整" : prevcoil.contains("T") ? "退火" : prevcoil.contains("K") ? "开平" : prevcoil.contains("F") ? "分条" : "原料";
			// 原料转库，2、酸洗接收原料，3、酸洗上料
			cd.setAppId("优特" + prevMName + "转库");
			
			// 一次结算后第一次生产点上料的时候，不抛 转库和接收原料  改抛 12AB
			// 该卷是否刚刚一次结算完：可以根据提单里是否有这卷的一次结算数据进行判断：
//			int isYcJs = this.getMapper(YdmProductDetailMapper.class).isHasYcJs(ypdM.getCoilno());
//			if (isYcJs <= 0) {
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
//			}
			
			// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
			// 对已有数据进行修改：
			cd.setDataTypeIdx("N");
//			cd.setProdTypeNo("CTR");
			cd.setManageip("YTSX");
			cd.setLocNo("YTSX");
			cd.setAppId("优特酸洗接收原料");
			
			// 20231130刘侣 废掉 xuli 20231229 来刘侣
//			if (isYcJs > 0) {
//				cd.setActivityId("12AB");
//				cd.setAppId("来料加工");
//			}
			// end
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// 三抛：酸洗上料（41，开始生产
			cd.setActivityId("41A");
			cd.setDataTypeIdx("O");
			cd.setAppId("优特酸洗上料");
			cd.setLastMill("YTSX");
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// end
		}
	    
	    
	    //日志
	    MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "交工", username, opr_time, mes.getMaterial_no(), null, null, null, "投料卷号："+mes.getMaterial_no() + "；下道工序为：" + nextP);
	    this.getMapper(MesOprLogMapper.class).insert(mol);
	    
	    //  --(3)、提交事务
		r.setState("200");
		r.setMsgInfo("交工成功!");
		return r;
	}
	
	
	
	
	/***
	 * 动作处理--取消交工按钮   
	 * object中：
	 * Pc_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOutOff(CommonPage<PlnPicklePlan> sum) throws Exception {
		ResultModel r=new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String userId = (String) this.getSession().getAttribute(HomeService.SESSION_USER_ID);
		String username = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		PlnPicklePlan psp = sum.getObject();
		
		Integer v_cnt;		
		//  --(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		if("".equals(psp.getPc_plan_no()) || "".equals(psp.getPc_plan_no())){
			r.setState("500");
			r.setMsgInfo("参数错误：作业计划号为空");
			return r;
		}
		// --(1)、验证酸洗作业计划主记录存在
		PlnPicklePlan pcp=new PlnPicklePlan();
		pcp.setMachine_code(sum.getMemo1());
		pcp.setPc_plan_no(psp.getPc_plan_no());
		int count = this.getMapper(PlnPicklePlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n作业计划主记录不存在！");
		}
		//    --(2.2)、验证酸洗作业计划明细记录存在
		PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setPc_plan_no(psp.getPc_plan_no());
		pcpd.setObject_no_vt(psp.getObject_no_vt());
		pcpd.setObject_no(psp.getMaterial_no());
		int count2 = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n虚拟卷号："+psp.getObject_no_vt()+""
					+ "\n原料卷号："+psp.getMaterial_no()+"\n作业计划明细记录不存在！");
		}
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"原料卷虚拟物料信息不存在！");
		}
		//???
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "mat_object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"出口卷虚拟物料信息不存在！");
		}
		//  --(3)、验证原料卷对应的酸洗主实绩存在，且为“未交工”状态
		MesPlmM mCross = new MesPlmM();
		mCross.setMachine_code(sum.getMemo1());
		mCross.setSchedule_no(psp.getPc_plan_no());
		mCross.setMaterial_no_vt(psp.getObject_no_vt());
		mCross.setMaterial_no(psp.getMaterial_no());
		v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
		if (v_cnt<=0) {
			r.setState("500");
			r.setMsgInfo("原料卷号：" +psp.getMaterial_no()+ "，当前不存在酸洗作业实绩！请确认是否已操作上料！");
			return r;
		}
	    List<MesPlmM> lmcam = this.getMapper(MesPlmMMapper.class).find(mCross, 0, 0);
	    MesPlmM v_rec_Rcm =lmcam.get(0);
	    if(v_rec_Rcm.getHand_over_status()!=null && !v_rec_Rcm.getHand_over_status().equals("1")){
	    	r.setState("500");
	    	r.setMsgInfo("原料卷号："+psp.getMaterial_no()+"还未生产交工！");
			return r;
	    }
	    
	    //******  设置物料在库  ******
		YdmProductDetail mypd=new YdmProductDetail();
		mypd.setCoilno(v_rec_Rcm.getMaterial_no());
		CommonPage<YdmProductDetail> ypdcp=new CommonPage<YdmProductDetail>();
		ypdcp.setObject(mypd);
		//判断物料是否允许撤销出库
		ResultModel rm = this.getBean(LmsApiServiceImpl.class).doDepend(ypdcp);
		if("500".equals(rm.getState())){
			throw new Exception(rm.getMsgInfo());
		}																																						
		this.getBean(LmsApiServiceImpl.class).doCancelOut(ypdcp);
				
	    MesPlmD v_rec_tpd=new MesPlmD();
	    v_rec_tpd.setProcess_no(v_rec_Rcm.getProcess_no());
	    List<MesPlmD> list_tpd = this.getMapper(MesPlmDMapper.class).find(v_rec_tpd, 0, 0);
	    if(list_tpd==null||list_tpd.size()==0){
			r.setState("500");
			r.setMsgInfo("作业计划原料卷不存在出口卷实绩!");
			return r;
		}
    	for(MesPlmD mcsq:list_tpd){
    		// 如果出口卷是边丝或者虚拟物料号为空,则按非计划执行
			if (Utils.isNotEmpty(mcsq.getCoil_no())  && "B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))){
				if (Utils.isNotEmpty(mcsq.getCoil_act_wgt()) && mcsq.getCoil_act_wgt().intValue()>0) {
					//则调用生产管理的【酸洗完成——实物 生成接口】 2018-06-22
					PrcMaterielRelation pmr=new PrcMaterielRelation();
					pmr.setObject_no(psp.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
					pmr.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
					this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_PrcMatRelRemove(pmr);
				}
				//或者虚拟物料号为空,则按非计划执行
			}else if (Utils.isEmpty(mcsq.getCoil_no_vt())) {
				//第二卷
				PrcMaterielRelation pmr2=new PrcMaterielRelation();
				pmr2.setObject_no(v_rec_Rcm.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmr2.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
				// 由于在交工的时候,生成对应的虚拟出口卷信息取消的时候将其直接删除 2018-09-10
				PlnMaterielDetail pmddetele2 = new PlnMaterielDetail();
				pmddetele2.setObject_no(mcsq.getCoil_no());
				pmddetele2.setOrd_flg("2");
				this.getMapper(PlnMaterielDetailMapper.class).doDeleteByOrdflg(pmddetele2);
				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_PrcMatRelRemove(pmr2);
				
			}else {
			//  --(2.10)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；
				PlnMaterielDetail pmdq=new PlnMaterielDetail();
				pmdq.setObject_no(mcsq.getCoil_no());
				pmdq.setObject_no_vt(mcsq.getCoil_no_vt());
				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_RelationCancel(pmdq);
			}
			// --------------------------------2018-06-22--------------------------------

			String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("6", psp.getObject_no_vt());
				
			if(nextProcessCode==null || "".equals(nextProcessCode)){
//					cp.setMemo1("500203");//成品库
				// 酸洗交工这里之前没有写入生产订单的已生产量：所以得补上20230908 刘侣
				//生产订单统计 统计量并修改生产订单状态
			    try{
			    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(mcsq.getCoil_no(),1,false);
			    }catch(Exception e){
			    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
			    	e.printStackTrace();
			    }
			}
			
			//清空所有出口卷实绩的虚拟出口卷号信息
			MesPlmD mcsd=new MesPlmD();
			mcsd.setUpdate_opr(username);
			mcsd.setUpdate_time(now);
			mcsd.setCoil_no(mcsq.getCoil_no());
			this.getMapper(MesPlmDMapper.class).update(mcsd);
    	}
	    	    
	    //    --(2.6)、如果产生了部分原卷吊销，则调用物流模块接口，
	    //验证吊销原卷（新卷号）为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；                                                                        
	    if("1".equals(v_rec_Rcm.getPartial_rejected()) && v_rec_Rcm.getRejected_coil_no()!=null){
	    	YdmProductDetail ypd=new YdmProductDetail();
			ypd.setCoilno(v_rec_Rcm.getRejected_coil_no());
			ypd.setState("0");
			List<YdmProductDetail> lypd=this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
			if(lypd==null||lypd.size()==0){
				throw new Exception("吊销卷["+v_rec_Rcm.getRejected_coil_no()+"]不为待入库状态");
			}else{
				//开始事务
				//如果酸洗产生了吊销的原料卷，调用物流模块（仓库管理）接口，吊销卷撤销库存实绩
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doInsertRevokeCanl(v_rec_Rcm.getRejected_coil_no());
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
			}
	    }
	    
	    for(MesPlmD mcsd:list_tpd){
			// 排除实重<=0的边丝
			if (mcsd.getCoil_no() != null && "B".equals(mcsd.getCoil_no().substring(mcsd.getCoil_no().length()-1))){
				if (mcsd.getCoil_act_wgt()==null || mcsd.getCoil_act_wgt().intValue()<=0) {
					continue;
				}
			}
			//   --(2.7)、调用物流模块接口，验证出口钢卷（coil_no）为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；
		    YdmProductDetail ypd=new YdmProductDetail();
			ypd.setCoilno(mcsd.getCoil_no());
			ypd.setState("-1");
			List<YdmProductDetail> lypd=this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
			if(lypd==null||lypd.size()==0){
				throw new Exception("出口钢卷["+mcsd.getCoil_no()+"]不为待入库状态");
			}else{
				//开始事务
				//调用物流模块（仓库管理）接口，删除钢卷库存实绩；
				CommonPage<YdmProductDetail> cp1=new CommonPage<YdmProductDetail>();
				YdmProductDetail ypdu=new YdmProductDetail();
				ypdu.setCoilno(mcsd.getCoil_no());
				cp1.setObject(ypd);
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doDeleteFinishedRoll(cp1);
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
			}
			
			//===============2019-03-12========质量检验委托开始=============================
  		    if(v_rec_Rcm.getSchedule_no()!=null && !"".equals(v_rec_Rcm.getSchedule_no())){//作业计划号不为空
  		    	try{
  		    		QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					List<PlnMaterielDetail> lpmdq22 = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
							"object_no_vt = '" + v_rec_Rcm.getMaterial_no_vt() + "' and nvl(invalid_flg,0) = '0'", null, 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(v_rec_Rcm.getMaterial_no_vt(), "A");
						// 获取工艺路径包含成分或者材质类
						if(judge_Contain_Qcm!=-1){
							ajsfp.setPline_seq((long)judge_Contain_Qcm);
  					  	ajsfp.setInspection_lot(mcsd.getInspection_lot());//检验号
	  					  	ajsfp.setBatch_no(v_rec_Rcm.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.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
							ajsfp.setMaterial_no(mcsd.getCoil_no());//取样材料号   
							ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
							ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
							ajsfp.setBoard_no(v_rec_Rcm.getMaterial_no());
							
							ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_Rcm.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("A");//工序代码    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(mcsd.getInspection_lot());
							CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
							sum22.setObject(qjsprem);
							this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
  						}
  					}
  				}catch(Exception e){
  					e.printStackTrace();
  				}
  		    }
  			//==========================质量检验委托结束==================================
			
			
		}
	    // 释放虚拟母卷
	    PlnMaterielDetail pmdq=new PlnMaterielDetail();
		pmdq.setObject_no_vt(psp.getObject_no_vt());
		List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).find(pmdq, 0, 1);
		this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_SumCancel(lpmdq.get(0));
	    
	    //  --(2.11)、修改酸洗作业主实绩交工状态
	    MesPlmM mes=new MesPlmM();
	    mes.setHand_over_status("0");
	    mes.setUpdate_opr(username);
	    mes.setUpdate_time(now);
	    mes.setMachine_code(sum.getMemo1());
	    mes.setSchedule_no(psp.getPc_plan_no());
	    mes.setMaterial_no_vt(psp.getObject_no_vt());
	    mes.setMaterial_no(psp.getMaterial_no());
	    mes.setProcess_no(v_rec_Rcm.getProcess_no());
	    //业务处理在sql中
	    this.getMapper(MesPlmMMapper.class).doUpdate3(mes);
	    
	    
	    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
		if ("1".equals(isOpen)) {
		
		    // 记录成本异动点：20230811刘侣
		    YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(psp.getMaterial_no());
	 		ComBaseCbYdd cd = new ComBaseCbYdd();
	 		cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
	 		cd.setInstDisp("01");
	 		cd.setDataTypeIdx("O");
	 		// 当前产线：
	 		String currentMachine = ypdM.getCoilno().contains("S") ? "YTSX" : ypdM.getCoilno().contains("L") ? "YTZZ" : ypdM.getCoilno().contains("P") ? "YTPZ" : ypdM.getCoilno().contains("T") ? "YTTH" : ypdM.getCoilno().contains("K") ? "YTHJ" : ypdM.getCoilno().contains("F") ? "YTZJ" : "YT1";
	 		cd.setLocNo(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setInvQtyUnit("块");
	 		cd.setInvWidth(ypdM.getWidth() != null ? String.valueOf(ypdM.getWidth()) : "0");
	 		cd.setCreateId(userId);
	 		cd.setActivityId("41A");
	 		cd.setInvLength(ypdM.getLength() != null ? String.valueOf(ypdM.getLength()) : "0");
	 		cd.setManageip(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setProdName(ypdM.getProd_name());
	 		cd.setInvThick(ypdM.getThick() != null ? String.valueOf(ypdM.getThick()) : "0");
	 		
	 		
	 		String prevcoil = ypdM.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) ? ypdM.getMaterailcoilno() : prevcoil); // 投料卷号
	 		cd.setSysId("IA");
	 		cd.setOrderItem(ypdM.getOrderno());
	 		cd.setCrntMill(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setBeTransUnit("t");
	 		cd.setExecJobFunc("D");
	 		ComBaseSteel cbs = this.getMapper(ComBaseSteelMapper.class).findById(ypdM.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(ypdM.getFactweight() != null ? ypdM.getFactweight() / 1000 : ypdM.getFactweight());
	 		cd.setProdTypeNo("CTR");
	 		cd.setAppId("优特钢酸洗取消上料");
	 		cd.setInvId("YT1".equals(currentMachine) ? ypdM.getMaterailcoilno() : ypdM.getCoilno());
	 		cd.setInvQty("1");

			// setSrcFac根据卷的物料属性去判断：20231031刘侣
			cd.setSrcFac("507101".equals(ypdM.getObject_attr()) ? "1" : "3");
			
	 		cd.setGrade("40740801".equals(ypdM.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 = ypdM.getCoilno().contains("S") ? "酸洗" : ypdM.getCoilno().contains("L") ? "冷轧" : ypdM.getCoilno().contains("P") ? "平整" : ypdM.getCoilno().contains("T") ? "退火" : ypdM.getCoilno().contains("K") ? "横剪" : ypdM.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(ypdM.getCoilno());
//			if (isYcJs <= 0) {
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
//			}
			
			// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
			// 对已有数据进行修改：
			cd.setDataTypeIdx("N");
//			cd.setProdTypeNo("CTR");
			cd.setManageip("YTSX");
			cd.setLocNo("YTSX");
			cd.setAppId("酸洗取消接收原料");
			
			// 20231130刘侣
//			if (isYcJs > 0) {
//				cd.setActivityId("12AB");
//				cd.setAppId("取消来料加工");
//			}
			// end
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// 三抛：酸洗上料（41，开始生产
			cd.setActivityId("41A");
			cd.setDataTypeIdx("O");
			cd.setAppId("酸洗取消上料");
			cd.setLastMill("YTSX");
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// end
		}
	    
	    
	    //日志
	    MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "取消交工", username, opr_time, mes.getMaterial_no(), null, null, null, "投料卷号："+mes.getMaterial_no());
	    this.getMapper(MesOprLogMapper.class).insert(mol);
	    
		r.setState("200");
		r.setMsgInfo("取消交工成功！");
		return r;
	}
	
	
	/***
	 * 动作处理--取消交工按钮   
	 * object中：
	 * Pc_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOutOffNew(CommonPage<PlnPicklePlan> sum) throws Exception {
		ResultModel r=new ResultModel();
		Date now = new Date();
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(now); //操作时间
		String userId = (String) this.getSession().getAttribute(HomeService.SESSION_USER_ID);
		String username = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		PlnPicklePlan psp = sum.getObject();
		
		Integer v_cnt;		
		//  --(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		if("".equals(psp.getPc_plan_no()) || "".equals(psp.getPc_plan_no())){
			r.setState("500");
			r.setMsgInfo("参数错误：作业计划号为空");
			return r;
		}
		// --(1)、验证酸洗作业计划主记录存在
		PlnPicklePlan pcp=new PlnPicklePlan();
		pcp.setMachine_code(sum.getMemo1());
		pcp.setPc_plan_no(psp.getPc_plan_no());
		int count = this.getMapper(PlnPicklePlanMapper.class).count(pcp);
		if (count<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n作业计划主记录不存在！");
		}
		//    --(2.2)、验证酸洗作业计划明细记录存在
		PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setPc_plan_no(psp.getPc_plan_no());
		pcpd.setObject_no_vt(psp.getObject_no_vt());
		pcpd.setObject_no(psp.getMaterial_no());
		int count2 = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+psp.getPc_plan_no()+"\n虚拟卷号："+psp.getObject_no_vt()+""
					+ "\n原料卷号："+psp.getMaterial_no()+"\n作业计划明细记录不存在！");
		}
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"原料卷虚拟物料信息不存在！");
		}
		//???
		v_cnt=this.getMapper(PlnMaterielDetailMapper.class).countWithCondition(null, "mat_object_no_vt='"+psp.getObject_no_vt()+"'");
		if (v_cnt<=0) {
			throw new Exception("虚拟卷号："+psp.getObject_no_vt()+"出口卷虚拟物料信息不存在！");
		}
		//  --(3)、验证原料卷对应的酸洗主实绩存在，且为“未交工”状态
		MesPlmM mCross = new MesPlmM();
		mCross.setMachine_code(sum.getMemo1());
		mCross.setSchedule_no(psp.getPc_plan_no());
		mCross.setMaterial_no_vt(psp.getObject_no_vt());
		mCross.setMaterial_no(psp.getMaterial_no());
		v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
		if (v_cnt<=0) {
			r.setState("500");
			r.setMsgInfo("原料卷号：" +psp.getMaterial_no()+ "，当前不存在酸洗作业实绩！请确认是否已操作上料！");
			return r;
		}
	    List<MesPlmM> lmcam = this.getMapper(MesPlmMMapper.class).find(mCross, 0, 0);
	    MesPlmM v_rec_Rcm =lmcam.get(0);
	    if(v_rec_Rcm.getHand_over_status()!=null && !v_rec_Rcm.getHand_over_status().equals("1")){
	    	r.setState("500");
	    	r.setMsgInfo("原料卷号："+psp.getMaterial_no()+"还未生产交工！");
			return r;
	    }
	    
	    //******  设置物料在库  ******
		YdmProductDetail mypd=new YdmProductDetail();
		mypd.setCoilno(v_rec_Rcm.getMaterial_no());
		CommonPage<YdmProductDetail> ypdcp=new CommonPage<YdmProductDetail>();
		ypdcp.setObject(mypd);
		//判断物料是否允许撤销出库
		ResultModel rm = this.getBean(LmsApiServiceImpl.class).doDepend(ypdcp);
		if("500".equals(rm.getState())){
			throw new Exception(rm.getMsgInfo());
		}																																						
		this.getBean(LmsApiServiceImpl.class).doCancelOut(ypdcp);
				
	    MesPlmD v_rec_tpd=new MesPlmD();
	    v_rec_tpd.setProcess_no(v_rec_Rcm.getProcess_no());
	    List<MesPlmD> list_tpd = this.getMapper(MesPlmDMapper.class).find(v_rec_tpd, 0, 0);
	    if(list_tpd==null||list_tpd.size()==0){
			r.setState("500");
			r.setMsgInfo("作业计划原料卷不存在出口卷实绩!");
			return r;
		}
    	for(MesPlmD mcsq:list_tpd){
    		// 如果出口卷是边丝或者虚拟物料号为空,则按非计划执行
			if (Utils.isNotEmpty(mcsq.getCoil_no())  && "B".equals(mcsq.getCoil_no().substring(mcsq.getCoil_no().length()-1))){
				if (Utils.isNotEmpty(mcsq.getCoil_act_wgt()) && mcsq.getCoil_act_wgt().intValue()>0) {
					//则调用生产管理的【酸洗完成——实物 生成接口】 2018-06-22
					PrcMaterielRelation pmr=new PrcMaterielRelation();
					pmr.setObject_no(psp.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
					pmr.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
					this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_PrcMatRelRemove(pmr);
				}
				//或者虚拟物料号为空,则按非计划执行
			}else if (Utils.isEmpty(mcsq.getCoil_no_vt())) {
				//第二卷
				PrcMaterielRelation pmr2=new PrcMaterielRelation();
				pmr2.setObject_no(v_rec_Rcm.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmr2.setSub_object_no(mcsq.getCoil_no());//MES_CR_SLITTING_D表的出口卷号
				// 由于在交工的时候,生成对应的虚拟出口卷信息取消的时候将其直接删除 2018-09-10
				PlnMaterielDetail pmddetele2 = new PlnMaterielDetail();
				pmddetele2.setObject_no(mcsq.getCoil_no());
				pmddetele2.setOrd_flg("2");
				this.getMapper(PlnMaterielDetailMapper.class).doDeleteByOrdflg(pmddetele2);
				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_PrcMatRelRemove(pmr2);
				
			}else {
			//  --(2.10)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；
				PlnMaterielDetail pmdq=new PlnMaterielDetail();
				pmdq.setObject_no(mcsq.getCoil_no());
				pmdq.setObject_no_vt(mcsq.getCoil_no_vt());
				this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_RelationCancel(pmdq);
			}
			// --------------------------------2018-06-22--------------------------------

			String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("6", psp.getObject_no_vt());
				
			if(nextProcessCode==null || "".equals(nextProcessCode)){
//					cp.setMemo1("500203");//成品库
				// 酸洗交工这里之前没有写入生产订单的已生产量：所以得补上20230908 刘侣
				//生产订单统计 统计量并修改生产订单状态
			    try{
			    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(mcsq.getCoil_no(),1,false);
			    }catch(Exception e){
			    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
			    	e.printStackTrace();
			    }
			}
			
			//清空所有出口卷实绩的虚拟出口卷号信息
			MesPlmD mcsd=new MesPlmD();
			mcsd.setUpdate_opr(username);
			mcsd.setUpdate_time(now);
			mcsd.setCoil_no(mcsq.getCoil_no());
			this.getMapper(MesPlmDMapper.class).update(mcsd);
    	}
	    	    
	    //    --(2.6)、如果产生了部分原卷吊销，则调用物流模块接口，
	    //验证吊销原卷（新卷号）为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；                                                                        
	    if("1".equals(v_rec_Rcm.getPartial_rejected()) && v_rec_Rcm.getRejected_coil_no()!=null){
	    	YdmProductDetail ypd=new YdmProductDetail();
			ypd.setCoilno(v_rec_Rcm.getRejected_coil_no());
			ypd.setState("0");
			List<YdmProductDetail> lypd=this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
			if(lypd==null||lypd.size()==0){
				throw new Exception("吊销卷["+v_rec_Rcm.getRejected_coil_no()+"]不为待入库状态");
			}else{
				//开始事务
				//如果酸洗产生了吊销的原料卷，调用物流模块（仓库管理）接口，吊销卷撤销库存实绩
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doInsertRevokeCanl(v_rec_Rcm.getRejected_coil_no());
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
			}
	    }
	    
	    for(MesPlmD mcsd:list_tpd){
			// 排除实重<=0的边丝
			if (mcsd.getCoil_no() != null && "B".equals(mcsd.getCoil_no().substring(mcsd.getCoil_no().length()-1))){
				if (mcsd.getCoil_act_wgt()==null || mcsd.getCoil_act_wgt().intValue()<=0) {
					continue;
				}
			}
			//   --(2.7)、调用物流模块接口，验证出口钢卷（coil_no）为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；
		    YdmProductDetail ypd=new YdmProductDetail();
			ypd.setCoilno(mcsd.getCoil_no());
			ypd.setState("-1");
			List<YdmProductDetail> lypd=this.getMapper(YdmProductDetailMapper.class).find(ypd, 0, 0);
			if(lypd==null||lypd.size()==0){
				throw new Exception("出口钢卷["+mcsd.getCoil_no()+"]不为待入库状态");
			}else{
				//开始事务
				//调用物流模块（仓库管理）接口，删除钢卷库存实绩；
				CommonPage<YdmProductDetail> cp1=new CommonPage<YdmProductDetail>();
				YdmProductDetail ypdu=new YdmProductDetail();
				ypdu.setCoilno(mcsd.getCoil_no());
				cp1.setObject(ypd);
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doDeleteFinishedRoll(cp1);
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
			}
			
//			//===============2019-03-12========质量检验委托开始=============================
//  		    if(v_rec_Rcm.getSchedule_no()!=null && !"".equals(v_rec_Rcm.getSchedule_no())){//作业计划号不为空
//  		    	try{
//  		    		QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
//					List<PlnMaterielDetail> lpmdq22 = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,
//							"object_no_vt = '" + v_rec_Rcm.getMaterial_no_vt() + "' and nvl(invalid_flg,0) = '0'", null, 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(v_rec_Rcm.getMaterial_no_vt(), "A");
//						// 获取工艺路径包含成分或者材质类
//						if(judge_Contain_Qcm!=-1){
//							ajsfp.setPline_seq((long)judge_Contain_Qcm);
//  					  	ajsfp.setInspection_lot(mcsd.getInspection_lot());//检验号
//	  					  	ajsfp.setBatch_no(v_rec_Rcm.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.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
//							ajsfp.setMaterial_no(mcsd.getCoil_no());//取样材料号   
//							ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
//							ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
//							ajsfp.setBoard_no(v_rec_Rcm.getMaterial_no());
//							
//							ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_Rcm.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("A");//工序代码    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(mcsd.getInspection_lot());
//							CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
//							sum22.setObject(qjsprem);
//							this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
//  						}
//  					}
//  				}catch(Exception e){
//  					e.printStackTrace();
//  				}
//  		    }
  			//==========================质量检验委托结束==================================
			
			
		}
	    // 释放虚拟母卷
	    PlnMaterielDetail pmdq=new PlnMaterielDetail();
		pmdq.setObject_no_vt(psp.getObject_no_vt());
		List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).find(pmdq, 0, 1);
		this.getBean(MesApiPicklePlanServiceImpl.class).PickleFinsh_SumCancel(lpmdq.get(0));
	    
	    //  --(2.11)、修改酸洗作业主实绩交工状态
	    MesPlmM mes=new MesPlmM();
	    mes.setHand_over_status("0");
	    mes.setUpdate_opr(username);
	    mes.setUpdate_time(now);
	    mes.setMachine_code(sum.getMemo1());
	    mes.setSchedule_no(psp.getPc_plan_no());
	    mes.setMaterial_no_vt(psp.getObject_no_vt());
	    mes.setMaterial_no(psp.getMaterial_no());
	    mes.setProcess_no(v_rec_Rcm.getProcess_no());
	    //业务处理在sql中
	    this.getMapper(MesPlmMMapper.class).doUpdate3(mes);
	    
	    
	    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
		if ("1".equals(isOpen)) {
		
		    // 记录成本异动点：20230811刘侣
		    YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(psp.getMaterial_no());
	 		ComBaseCbYdd cd = new ComBaseCbYdd();
	 		cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
	 		cd.setInstDisp("01");
	 		cd.setDataTypeIdx("O");
	 		// 当前产线：
	 		String currentMachine = ypdM.getCoilno().contains("S") ? "YTSX" : ypdM.getCoilno().contains("L") ? "YTZZ" : ypdM.getCoilno().contains("P") ? "YTPZ" : ypdM.getCoilno().contains("T") ? "YTTH" : ypdM.getCoilno().contains("K") ? "YTHJ" : ypdM.getCoilno().contains("F") ? "YTZJ" : "YT1";
	 		cd.setLocNo(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setInvQtyUnit("块");
	 		cd.setInvWidth(ypdM.getWidth() != null ? String.valueOf(ypdM.getWidth()) : "0");
	 		cd.setCreateId(userId);
	 		cd.setActivityId("41A");
	 		cd.setInvLength(ypdM.getLength() != null ? String.valueOf(ypdM.getLength()) : "0");
	 		cd.setManageip(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setProdName(ypdM.getProd_name());
	 		cd.setInvThick(ypdM.getThick() != null ? String.valueOf(ypdM.getThick()) : "0");
	 		
	 		
	 		String prevcoil = ypdM.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) ? ypdM.getMaterailcoilno() : prevcoil); // 投料卷号
	 		cd.setSysId("IA");
	 		cd.setOrderItem(ypdM.getOrderno());
	 		cd.setCrntMill(currentMachine); // 填当前产线：优特酸选 YTSX,优特轧制YTZZ,优特平整YTPZ,优特退火YTTH,优特横剪YTHJ,优特纵剪YTZJ
	 		cd.setBeTransUnit("t");
	 		cd.setExecJobFunc("D");
	 		ComBaseSteel cbs = this.getMapper(ComBaseSteelMapper.class).findById(ypdM.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(ypdM.getFactweight() != null ? ypdM.getFactweight() / 1000 : ypdM.getFactweight());
	 		cd.setProdTypeNo("CTR");
	 		cd.setAppId("优特钢酸洗取消上料");
	 		cd.setInvId("YT1".equals(currentMachine) ? ypdM.getMaterailcoilno() : ypdM.getCoilno());
	 		cd.setInvQty("1");

			// setSrcFac根据卷的物料属性去判断：20231031刘侣
			cd.setSrcFac("507101".equals(ypdM.getObject_attr()) ? "1" : "3");
			
	 		cd.setGrade("40740801".equals(ypdM.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 = ypdM.getCoilno().contains("S") ? "酸洗" : ypdM.getCoilno().contains("L") ? "冷轧" : ypdM.getCoilno().contains("P") ? "平整" : ypdM.getCoilno().contains("T") ? "退火" : ypdM.getCoilno().contains("K") ? "横剪" : ypdM.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(ypdM.getCoilno());
//			if (isYcJs <= 0) {
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
//			}
			
			// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
			// 对已有数据进行修改：
			cd.setDataTypeIdx("N");
//			cd.setProdTypeNo("CTR");
			cd.setManageip("YTSX");
			cd.setLocNo("YTSX");
			cd.setAppId("酸洗取消接收原料");
			
			// 20231130刘侣
//			if (isYcJs > 0) {
//				cd.setActivityId("12AB");
//				cd.setAppId("取消来料加工");
//			}
			// end
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// 三抛：酸洗上料（41，开始生产
			cd.setActivityId("41A");
			cd.setDataTypeIdx("O");
			cd.setAppId("酸洗取消上料");
			cd.setLastMill("YTSX");
			this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
			// end
		}
	    
	    
	    //日志
	    MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "取消交工", username, opr_time, mes.getMaterial_no(), null, null, null, "投料卷号："+mes.getMaterial_no());
	    this.getMapper(MesOprLogMapper.class).insert(mol);
	    
		r.setState("200");
		r.setMsgInfo("取消交工成功！");
		return r;
	}
	
	
	
	
	/**
	 * 动作处理_下发PDI
	 * objectlist中：
	 * pc_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 * */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel Plm01L3SendPdi(CommonPage<PlnPicklePlan> sum) 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);
		String WORK_GRP = (String) this.getSession().getAttribute(HomeService.SESSION_WORK_GRP); //班组
		String WORK_ORD = (String) this.getSession().getAttribute(HomeService.SESSION_WORK_ORD); //班次
		List<PlnPicklePlan> pppList = sum.getObjectList();
		//20200731 下发PDI固定一人操作，不做班组的控制
		/*if (WORK_GRP == null|| (!WORK_GRP.equals("1") && !WORK_GRP.equals("2") && !WORK_GRP.equals("3") && !WORK_GRP.equals("4"))) {
			rm.setMsgInfo("班组代码：" + sum.getMemo2() + "无效，\n只能是 1（甲班）或2（乙班）或3（丙班）或4（丁班）！请选择正确的班组，重新登录系统!");
			rm.setState("500");
			return rm;
		}*/
		if(sum.getMemo1()==null || "".equals(sum.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("参数错误：机台代码不能为空！");
			return rm;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			rm.setState("500");
			rm.setMsgInfo("参数错误：未指定需要下发PDI的钢卷信息！");
			return rm;
		}
		for(PlnPicklePlan plp: pppList){
			if("".equals(plp.getPc_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：作业计划号、原料卷号个数不匹配！");
				return rm;
			}
		}
		//验证机台基础信息存在
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(sum.getMemo1());
		int count = this.getMapper(ComBaseMachineMapper.class).count(machine);
		if (count <= 0) {
			rm.setMsgInfo("机台代码：" + sum.getMemo1() + "，\n机台基础信息不存在！");
			rm.setState("500");
			return rm;
		}
		//机台:获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
		ComBaseMachine machine2 = new ComBaseMachine();
		machine2.setMachine_code(sum.getMemo1());
		List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class).find(machine2, 0, 0);
		String v_mch_mark=lcbm.get(0).getMachine_mark();
		if (v_mch_mark == null) {
			rm.setMsgInfo("机台代码：" + v_mch_mark + "\n设备编号未配置，无法处理！");
			rm.setState("500");
			return rm;
		}
		
		//获取2级系统未酸洗的数据
		List<String> coilList = this.getBean(MesSxWeightServiceImpl.class).doQuaryCoilPdiInfo(); 		  
		 
		//******************************** 循环勾选的数据，单条进行操作  *******************************************
		for(PlnPicklePlan plp: sum.getObjectList()){
			if(plp.getPc_plan_no()==null || "".equals(plp.getPc_plan_no())){
				rm.setMsgInfo("作业计划号为空");
				rm.setState("500");
				return rm;
			}
			if(plp.getObject_no_vt()==null || "".equals(plp.getObject_no_vt())){
				rm.setMsgInfo("虚拟卷号为空");
				rm.setState("500");
				return rm;
			}
			if(plp.getMaterial_no()==null || "".equals(plp.getMaterial_no())){
            	rm.setMsgInfo("投料卷号为空");
				rm.setState("500");
				return rm;
			}
			
			try{
				//验证酸洗作业计划主记录存在
				PlnPicklePlan psp=new PlnPicklePlan();
				psp.setMachine_code(sum.getMemo1());
				psp.setPc_plan_no(plp.getPc_plan_no());
				count = this.getMapper(PlnPicklePlanMapper.class).count(psp);
				if (count<=0) {
					throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getPc_plan_no()+"\n作业计划主记录不存在！");
				}
				//验证酸洗作业计划明细记录存在
				PlnPicklePlanDetail pcpd=new PlnPicklePlanDetail();
				pcpd.setMachine_code(sum.getMemo1());
				pcpd.setPc_plan_no(plp.getPc_plan_no());
				pcpd.setObject_no_vt(plp.getObject_no_vt());
				pcpd.setObject_no(plp.getMaterial_no());
				count = this.getMapper(PlnPicklePlanDetailMapper.class).count(pcpd);
				if (count<=0) {
					throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getPc_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
							+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
				}
				//酸洗计划明细表
				PlnPicklePlanDetail cuttdel = new PlnPicklePlanDetail();
				cuttdel.setMachine_code(sum.getMemo1());
				cuttdel.setPc_plan_no(plp.getPc_plan_no());
				cuttdel.setObject_no_vt(plp.getObject_no_vt());
				cuttdel.setObject_no(plp.getMaterial_no());
				List<PlnPicklePlanDetail> v_rec_pln_d = this.getMapper(PlnPicklePlanDetailMapper.class).findWithCondition(cuttdel, null, null, 0, 0);
				//虚拟物料表
				PlnMaterielDetail tYdm = new PlnMaterielDetail();
				tYdm.setObject_no_vt(plp.getObject_no_vt());
				List<PlnMaterielDetail> v_rec_mtr_in = this.getBean(PlnMaterielDetailMapper.class).findWithCondition(tYdm, null,null, 0, 0);				
				// 9.2 大 写字母'K' + 6位日期（YYMMDD，取数据库时间） + 2位纵剪设备编号（不足为前面补0）
				SimpleDateFormat formatY3 = new SimpleDateFormat("yyMMdd");
				String v_process_no = "X" + formatY3.format(now)+lpad(v_mch_mark, 2, "0");
				Integer serialno = this.getMapper(MesPlmMMapper.class).doquery(v_process_no);
				if (serialno == null) {
					serialno = 1;
				}
				v_process_no = v_process_no + lpad(serialno.toString(), 3, "0");
				
				//******   新增酸洗生产主实绩  ******
				MesPlmM mcam=new MesPlmM();
				mcam.setProcess_no(v_process_no);
				mcam.setMachine_code(sum.getMemo1());
				mcam.setSchedule_no(plp.getPc_plan_no());
				mcam.setInner_seq(v_rec_pln_d.get(0).getPc_seq());//计划内序号
				mcam.setMaterial_no_vt(plp.getObject_no_vt());
				//原料卷计划规格、牌号等信息来源于 pln_materiel_detail 表
				mcam.setPln_steel_code(v_rec_mtr_in.get(0).getSteel_code());
				mcam.setPln_mtr_thk(v_rec_mtr_in.get(0).getThick());
				mcam.setPln_mtr_wdt(v_rec_mtr_in.get(0).getWidth());
				mcam.setPln_mtr_len(v_rec_mtr_in.get(0).getLength());
				mcam.setPln_mtr_inn_dia(v_rec_mtr_in.get(0).getDiameter_inn());
				mcam.setPln_mtr_out_dia(v_rec_mtr_in.get(0).getDiameter_out());
				mcam.setPln_mtr_thr_wgt(v_rec_mtr_in.get(0).getSingle_weight());
				mcam.setSteel_code(v_rec_pln_d.get(0).getSteel_code());//牌号取订单的牌号
				//原料卷实际规格、牌号等信息来源于 ydm_product_detail 表
				YdmProductDetail ypd = this.getMapper(YdmProductDetailMapper.class).doFind(plp.getMaterial_no(), null);
				if (ypd!=null) {					
					mcam.setMaterial_no(plp.getMaterial_no());//原料卷号
					mcam.setMaterial_no_src(ypd.getMaterailcoilno());
					mcam.setMtr_thk(ypd.getThick());
					mcam.setMtr_wdt(ypd.getWidth());
					mcam.setMtr_len(ypd.getLength());
					mcam.setMtr_inn_dia(ypd.getDiameter_inn());
					mcam.setMtr_out_dia(ypd.getDiameter_out());
					mcam.setMtr_thr_wgt(ypd.getTheoryweight());
					mcam.setMtr_act_wgt(ypd.getFactweight());
				}
				mcam.setWrk_date(new SimpleDateFormat("yyyy-MM-dd").format(now));
				mcam.setWrk_ord(WORK_ORD);
				mcam.setWrk_grp(WORK_GRP);
				mcam.setFeeding_time(now);
				mcam.setPartial_rejected("0");				
				mcam.setHand_over_status("0");
				mcam.setCreate_opr(userName);
				mcam.setCreate_time(now);				
				this.getMapper(MesPlmMMapper.class).insert(mcam);			
				
				//****** 新增酸洗出口卷实绩(子表)	******																																									
				//出口卷实际规格、牌号等信息来源于 ydm_product_detail 表	
				MesPlmD mpd = new MesPlmD();
				String sql = "select count(1) from mes_plm_m t left join mes_plm_d d on t.process_no = d.process_no "
						+ "where t.material_no_src = '"+mcam.getMaterial_no_src()+"' and substr(d.coil_no,-1,1) not in ('B','H')";	
				int countSum = this.getMapper(PbModelDbMapper.class).doQueryCount(sql);
				countSum++;
				String coilno=plp.getMaterial_no().substring(0, 8) + "S"+ lpad(v_mch_mark, 2, "0")+"0"+countSum;				 
				mpd.setCoil_no(coilno);//成品卷号
				mpd.setCoil_no_vt(plp.getObject_no_vt());
				mpd.setProcess_no(mcam.getProcess_no());
				mpd.setWrk_date(mcam.getWrk_date());
				mpd.setWrk_ord(WORK_ORD);
				mpd.setWrk_grp(WORK_GRP);
				mpd.setSteel_code(mcam.getSteel_code());
				//20200807 :易XP XG130Q(1204)经过酸洗 自动转换成 XG130QR(1173)
				if ("1204".equals(mpd.getSteel_code())) {
					mpd.setSteel_code("1173");
				}
				//出口卷计划规格、牌号等信息来源于 pln_materiel_detail表
				PlnMaterielDetail pmd22=new PlnMaterielDetail();
				pmd22.setMat_object_no_vt(plp.getObject_no_vt());
				List<PlnMaterielDetail> pmdList=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(pmd22, ""," serial_no ",0,0);
				if (pmdList!=null && pmdList.size()>0) {
					mpd.setProd_order_no(pmdList.get(0).getProd_order_no());//生产订单号
					mpd.setOrder_no(pmdList.get(0).getOrder_no());//订单号
					mpd.setAim_thk(pmdList.get(0).getThick());
					mpd.setAim_wdt(pmdList.get(0).getWidth());
					mpd.setAim_len(pmdList.get(0).getLength());
					mpd.setAim_inn_dia(pmdList.get(0).getDiameter_inn());//目标内径
					mpd.setAim_out_dia(pmdList.get(0).getDiameter_out());
					mpd.setPk_ask_code(pmdList.get(0).getPk_ask_code());
					mpd.setPk_ask_desc(pmdList.get(0).getPk_ask_desc());
				}			 
				mpd.setProduce_time(now);				 
				mpd.setReceive_time(now);
				mpd.setReceive_opr(userName);
				mpd.setCreate_opr(userName);
				mpd.setCreate_time(now);				
				this.getMapper(MesPlmDMapper.class).insert(mpd);
				
				//****** 下发到2级的酸洗计划接收表  ******
				Tbs02L2PltcmReceiveData t = new Tbs02L2PltcmReceiveData();
				String fidmax=this.getMapper(Tbs02L2PltcmProSeqMapper.class).doQueryMaxFid(opr_time);
				if(fidmax==null){
					fidmax="001";
				}else {
					String seq = fidmax.substring(fidmax.length() - 3);
					int iseq = Integer.parseInt(seq) + 1;
					fidmax = String.format("%03d", iseq);
				}
				t.setFid(opr_time+fidmax);
				t.setFlag("1");
				if (ypd!=null) {
					ComBaseSteel cbs = this.getMapper(ComBaseSteelMapper.class).findById(mpd.getSteel_code());
					if (cbs!=null) {						
						t.setAlloy_grd(cbs.getSteel_name());//牌号
					}
					t.setCoil_no(ypd.getMaterailcoilno());//原料卷号
					t.setCoil_thk(ypd.getThick()!=null?String.valueOf(ypd.getThick()):"");//厚宽
					t.setCoil_wth(ypd.getWidth()!=null?String.valueOf(ypd.getWidth()):"");
					t.setCoil_india(ypd.getDiameter_inn()!=null?String.valueOf(ypd.getDiameter_inn()):"");//外径，内径
					t.setCoil_outdia(ypd.getDiameter_out()!=null?String.valueOf(ypd.getDiameter_out()):"");
					t.setReser1(plp.getMaterial_no());
					t.setReser2(null);
					t.setReser3(null);
					t.setC_coil_no(coilno);//成品卷号
					t.setCreate_time(now);
					t.setStandard_no(ypd.getStd_name());
					t.setCoil_len(ypd.getLength()!=null?String.valueOf(ypd.getLength()):"");
					t.setCoil_wgt(ypd.getFactweight()+"");
					if (mpd.getOrder_no()!=null && mpd.getOrder_no().length()>3) {						
						String condition = " contract_no||contract_line_seq ='"+mpd.getOrder_no().substring(0,mpd.getOrder_no().length()-3)+"' and valid_flag = '1'";
						List<SlmContractLineInfo> scliList = this.getMapper(SlmContractLineInfoMapper.class).findWithCondition(null, condition, null, 0, 0);
						if (scliList!=null && scliList.size()>0) {						
							t.setOrder_thk(scliList.get(0).getThick()!=null?String.valueOf(scliList.get(0).getThick()):"");
							t.setOrder_wth(scliList.get(0).getWidth()!=null?String.valueOf(scliList.get(0).getWidth()):"");
						}
					}
					//在原有的2级未酸洗的卷的基础上，加上新的卷
					coilList.add(ypd.getMaterailcoilno());
				}
				this.getMapper(Tbs02L2PltcmReceiveDataMapper.class).insert(t);
				//发送到2级酸洗计划表
				 rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxPlanInfo(t);
				 if (!"200".equals(rm.getState())) {
					rm.setState("500");
					rm.setMsgInfo("插入酸洗计划接收表失败");
					return rm;
				}
				 
				//******  修改标识位，代表已下发 ******
				this.getMapper(PlnPicklePlanDetailMapper.class).doUpdatePlm(plp.getPc_plan_no(),plp.getObject_no_vt(),"1");
			}catch(Exception e){
				throw new Exception(e.getMessage());
			}			
		}
		
		//****** 下发到2级的酸洗顺序表  ******		
		Long maxseq=this.getMapper(Tbs02L2PltcmProSeqMapper.class).doQueryMax();
		//100条以内	
		if (coilList!=null && coilList.size()<=100) {	
			Tbs02L2PltcmProSeq tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			new SxUtil().doAddMsg(tsq, coilList);
			tsq.setSeq_no(maxseq+1);
			tsq.setNo_coils((long)coilList.size());
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);		
			//下发顺序到2级
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq);
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}			
		}else if (coilList.size()>100 && coilList.size()<=200) {
			//第1~~100条
			Tbs02L2PltcmProSeq tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList1 = coilList.subList(0, 100);
			new SxUtil().doAddMsg(tsq, subList1);
			tsq.setSeq_no(maxseq+1);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);					
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq); //下发顺序到2级
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
			
			//第100~~200条记录
			tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList2 = coilList.subList(100, coilList.size());
			new SxUtil().doAddMsg(tsq, subList2);
			tsq.setSeq_no(maxseq+2);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);		
			//下发顺序到2级
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq);
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
		}else if (coilList.size()>200 && coilList.size()<=300) {
			//第1~~100条
			Tbs02L2PltcmProSeq tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList1 = coilList.subList(0, 100);
			new SxUtil().doAddMsg(tsq, subList1);
			tsq.setSeq_no(maxseq+1);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);					
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq); //下发顺序到2级
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
			
			//第100~~200条记录
			tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList2 = coilList.subList(100, 200);
			new SxUtil().doAddMsg(tsq, subList2);
			tsq.setSeq_no(maxseq+2);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);		
			//下发顺序到2级
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq);
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
			
			//第200~~300条记录
			tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList3 = coilList.subList(200, coilList.size());
			new SxUtil().doAddMsg(tsq, subList3);
			tsq.setSeq_no(maxseq+3);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);		
			//下发顺序到2级
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq);
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
		}else if (coilList.size()>300 && coilList.size()<=400) {
			//第1~~100条
			Tbs02L2PltcmProSeq tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList1 = coilList.subList(0, 100);
			new SxUtil().doAddMsg(tsq, subList1);
			tsq.setSeq_no(maxseq+1);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);					
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq); //下发顺序到2级
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
			
			//第100~~200条记录
			tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList2 = coilList.subList(100, 200);
			new SxUtil().doAddMsg(tsq, subList2);
			tsq.setSeq_no(maxseq+2);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);		
			//下发顺序到2级
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq);
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
			//第200~~300条记录
			tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList3 = coilList.subList(200, 300);
			new SxUtil().doAddMsg(tsq, subList3);
			tsq.setSeq_no(maxseq+3);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);		
			//下发顺序到2级
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq);
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
			//第300~~400条记录
			tsq = new Tbs02L2PltcmProSeq();		
			tsq.setTrans_dtime(now);
			tsq.setMsg_flag("1");
			tsq.setNo_coils((long)sum.getObjectList().size());
			tsq.setSend_dc("3C");
			tsq.setReceive_dc("PT");
			tsq.setCreate_time(now);
			List<String> subList4 = coilList.subList(300, coilList.size());
			new SxUtil().doAddMsg(tsq, subList4);
			tsq.setSeq_no(maxseq+4);
			tsq.setNo_coils((long)coilList.size());//钢卷数取总计数
			this.getMapper(Tbs02L2PltcmProSeqMapper.class).insert(tsq);		
			//下发顺序到2级
			rm = this.getBean(MesSxWeightServiceImpl.class).doSendSxSeqInfo(tsq);
			if (!"200".equals(rm.getState())) {
				rm.setState("500");
				rm.setMsgInfo("插入酸洗顺序表失败");
				return rm;
			}
		}
		
		for (PlnPicklePlan pp : pppList) {
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "下发PDI", userName, opr_time, pp.getObject_no(), null, null, null, null);
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		rm.setMsgInfo("下发成功");
		rm.setState("200");
		return rm;
	}
	
	/**
	 * 动作处理_撤销PDI
	 * objectlist中：
	 * pc_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 * */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doCancelPlmPDI(CommonPage<PlnPicklePlan> sum) 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);
		
		if(sum.getMemo1()==null || "".equals(sum.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("参数错误：机台代码不能为空！");
			return rm;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			rm.setState("500");
			rm.setMsgInfo("参数错误：未指定需要撤销下发PDI的原料卷信息！");
			return rm;
		}
		
		int v_cnt = 0;
		for(PlnPicklePlan plp: sum.getObjectList()){
			if("".equals(plp.getPc_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return rm;
			}
			
			MesPlmM mCross = new MesPlmM();
			mCross.setSchedule_no(plp.getPc_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesPlmMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在酸洗作业主实绩！");
			}
		    List<MesPlmM> lmcam = this.getMapper(MesPlmMMapper.class).find(mCross, 0, 0);
		    MesPlmM v_rec_Rcm =lmcam.get(0);
		    if(v_rec_Rcm.getHand_over_status()!=null && !v_rec_Rcm.getHand_over_status().equals("0")){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能撤销pdi！！");
		    }
			
		}
		
		//--(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnPicklePlan plp: sum.getObjectList()){
			try{
				//******  删除酸洗生产主实绩 ******
				MesPlmM mpm = new MesPlmM();
				mpm.setMachine_code(sum.getMemo1());
				mpm.setSchedule_no(plp.getPc_plan_no());
				mpm.setMaterial_no_vt(plp.getObject_no_vt());
				mpm.setMaterial_no(plp.getMaterial_no());
				List<MesPlmM> mpmList = this.getBean(MesPlmMMapper.class).find(mpm, 0, 0);
				if (mpmList!=null && mpmList.size()>0) {
					for (MesPlmM mesM : mpmList) {
						//******  删除酸洗生产子信息 ******
						MesPlmD mpd = new MesPlmD();
						mpd.setProcess_no(mesM.getProcess_no());
						List<MesPlmD> mpdList = this.getMapper(MesPlmDMapper.class).find(mpd, 0, 0);
						if (mpdList!=null && mpdList.size()>0) {
							for (MesPlmD mesD : mpdList) {
								//执行删除子表
								this.getMapper(MesPlmDMapper.class).delete(mesD.getCoil_no());
							}
						}
						//执行生产主实绩 
						this.getMapper(MesPlmMMapper.class).delete(mesM.getProcess_no());
					}
				}											
				
				String condition = " RESER1='"+plp.getMaterial_no()+"'";
				List<Tbs02L2PltcmReceiveData> rList = this.getMapper(Tbs02L2PltcmReceiveDataMapper.class).findWithCondition(null, condition, null,0,0);
				if (rList!=null) {
					for (Tbs02L2PltcmReceiveData r : rList) {						
						rm = this.getBean(MesSxWeightServiceImpl.class).doCancelSendPlanSxInfo(r.getFid());
						if (!"200".equals(rm.getState())) {
							rm.setState("500");
							rm.setMsgInfo("删除酸洗计划接收表失败");
							return rm;
						}
						rm = this.getBean(MesSxWeightServiceImpl.class).doCancelSendCoilInfo(r.getCoil_no()); 
						if (!"200".equals(rm.getState())) {
							rm.setState("500");
							rm.setMsgInfo("删除酸洗卷信息表失败");
							return rm;
						}
					}
				}
				// ****** 调整成未下发状态   ******
				this.getMapper(PlnPicklePlanDetailMapper.class).doUpdatePlm(plp.getPc_plan_no(),plp.getObject_no_vt(),"0");
			}catch(Exception e){
				
			}
		}
		
		for (PlnPicklePlan ppp: sum.getObjectList()) {
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "撤销PDI", username, opr_time, ppp.getObject_no(), null, null, null, null);
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		rm.setMsgInfo("撤销下发成功");
		rm.setState("200");
		return rm;
	}
	
	
	/**
	 * 重量分配    和4mm酸洗一样          lw_plan_no改为Pc_plan_no
	 * @param memo1 重量
	 * @param memo2 重量来源 （1：采集、2：人工）
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doWeightDistribution1(CommonPage<PlnPicklePlanDetailAndMesPlmD> 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);
		PlnPicklePlanDetail ppp = oci.getObject().getMain();
		
		//验证选中的作业计划主表记录存在
		PlnPicklePlan plp=new PlnPicklePlan();
		plp.setMachine_code(ppp.getMachine_code());
		plp.setPc_plan_no(ppp.getPc_plan_no());
		List<PlnPicklePlan> lplp=this.getMapper(PlnPicklePlanMapper.class).find(plp, 0, 0);
		if(lplp==null||lplp.size()==0){
			rm.setState("500");
			rm.setMsgInfo("选中的作业计划记录不存在");
			return rm;
		}
		//验证选中的作业计划明细表记录存在
		PlnPicklePlanDetail plpd=new PlnPicklePlanDetail();
		plpd.setMachine_code(ppp.getMachine_code());
		plpd.setPc_plan_no(ppp.getPc_plan_no());
		plpd.setObject_no_vt(ppp.getObject_no_vt());
		plpd.setObject_no(ppp.getObject_no());
		List<PlnPicklePlanDetail> lplpd=this.getMapper(PlnPicklePlanDetailMapper.class).find(plpd, 0, 0);
		if(lplpd==null||lplpd.size()==0){
			rm.setState("500");
			rm.setMsgInfo("选中的作业计划明细记录不存在");
			return rm;
		}
		//验证选中的作业计划对应的酸洗主实绩存在
		MesPlmM mcsm=new MesPlmM();
		mcsm.setMachine_code(ppp.getMachine_code());
		mcsm.setSchedule_no(ppp.getPc_plan_no());
		mcsm.setMaterial_no_vt(ppp.getObject_no_vt());
		mcsm.setMaterial_no(ppp.getObject_no());
		List<MesPlmM> lmcsm=this.getMapper(MesPlmMMapper.class).find(mcsm, 0, 0);
		if(lmcsm==null||lmcsm.size()==0){
			rm.setState("500");
			rm.setMsgInfo("["+mcsm.getMaterial_no_vt()+"]酸洗主实绩不存在！");
			return rm;
		}
		if(!"0".equals(lmcsm.get(0).getHand_over_status())
				&&lmcsm.get(0).getHand_over_status()!=null){
			rm.setState("500");
			rm.setMsgInfo("["+mcsm.getMaterial_no_vt()+"]酸洗已生产交工！");
			return rm;
		}
		// 6.、验证原料卷，当前已有出口卷实绩
		MesPlmD mcccd=new MesPlmD();
		mcccd.setProcess_no(lmcsm.get(0).getProcess_no());
		List<MesPlmD> lmcsdxxx =this.getMapper(MesPlmDMapper.class).findWithCondition(mcccd,"coil_no not like '%B'", " coil_no ", 0, 0);
		if(lmcsdxxx==null||lmcsdxxx.size()==0){
			throw new Exception("作业计划原料卷不存在出口卷实绩!");
		}
		
		if(oci.getMemo1()==null || "".equals(oci.getMemo1().trim())){
			rm.setState("500");
			rm.setMsgInfo("请输入重量！");
			return rm;
		}			
		
		//开始事务：
		int icount=0;
		String dt=new SimpleDateFormat("yyMMdd").format(now);
		List<MesPlmWgt> lmcw=this.getMapper(MesPlmWgtMapper.class).findWithCondition(null, " substr(serial_no,1,6)='"+dt+"'", " serial_no desc", 0, 1);
		if(lmcw==null||lmcw.size()==0){
			icount=1;
		}else{
			icount=Integer.parseInt(lmcw.get(0).getSerial_no().substring(6,11))+1;
		}
		//创建酸洗出口卷线上称重实绩记录，即将前端传入的重量信息插入一条记录到MES_CR_SLITTING_WGT表中
		MesPlmWgt mcsw=new MesPlmWgt();
		mcsw.setSerial_no(dt+String.format("%05d", icount++));
		mcsw.setDivide_flag("1");
		mcsw.setDivide_opr(username);
		mcsw.setDivide_time(now);
		mcsw.setProcess_no(lmcsm.get(0).getProcess_no());
		mcsw.setWgt_source(oci.getMemo2());
		mcsw.setWgt_time(now);
		mcsw.setWgt_value(Double.parseDouble(oci.getMemo1()));
		this.getMapper(MesPlmWgtMapper.class).insert(mcsw);
				
		//查询所有出口卷实绩
		MesPlmD mcsdqq=new MesPlmD();
		mcsdqq.setProcess_no(lmcsm.get(0).getProcess_no());
		List<MesPlmD> lmcsdq = this.getMapper(MesPlmDMapper.class).findWithCondition(mcsdqq, " coil_no not like '%B' ", "coil_no", 0, 0);
		double v_sum=0;//理重计算值
		for(MesPlmD cur_01:lmcsdq){
        	if(cur_01.getAct_thk() ==null || cur_01.getAct_thk() <= 0){
				throw new Exception("出口卷:"+cur_01.getCoil_no()+"厚度必须大于0！");
			}
			if(cur_01.getAct_wdt() ==null || cur_01.getAct_wdt() <= 0){
				throw new Exception("出口卷:"+cur_01.getCoil_no()+"宽度必须大于0！");
			}
			if(cur_01.getAct_len() ==null || cur_01.getAct_len() <= 0){
				//throw new Exception("出口卷:"+cur_01.getCoil_no()+"长度必须大于0！");
			}
			v_sum+=(cur_01.getAct_wdt()==null?0:cur_01.getAct_wdt())*(cur_01.getAct_len()==null?0:cur_01.getAct_len())*(cur_01.getAct_thk()==null?0:cur_01.getAct_thk());
        }
		
		// （10'）、逐一循环出口卷实绩（废副品物料除外），重新计算各出口卷理重值：= 原卷理重 * （宽度*长度*块数）/ ∑（宽度*长度*块数）
		
		double sumWeight=Double.parseDouble(oci.getMemo1());//总重量
		List<MesPlmD> lmccd = this.getMapper(MesPlmDMapper.class).doQueryMes(lmcsm.get(0).getProcess_no());
		double lastWgt=0;
		for(MesPlmD d:lmccd){
		   // （10.1'）、前N-1个出口卷理重 = 原卷理重 * （宽度*长度*厚度）/ ∑（宽度*长度*厚度）
			//四舍五入
			BigDecimal b=null;
			double f1=0;
			if(Integer.parseInt(d.getXh())<Integer.parseInt(d.getCnt())){
				b= new BigDecimal(sumWeight*d.getAct_wdt()*d.getAct_len()*d.getAct_thk()/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(sumWeight-lastWgt);  
				f1 = b.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
			}
			MesPlmD mccccd=new MesPlmD();
			mccccd.setCoil_no(d.getCoil_no());
			mccccd.setCoil_thr_wgt(f1);
			this.getMapper(MesPlmDMapper.class).update(mccccd);
		}
	   
		//日志
	   	MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "重量分配", username, opr_time, ppp.getObject_no(), null, null, null, null);
	   	this.getMapper(MesOprLogMapper.class).insert(mol);
	   
		rm.setState("200");
		return rm;
	}
	
	/**
	 * 动作处理_称重保存  --仿照4mm酸洗   Pc_plan_no改为Pc_plan_no 机台代码什么的
	 * @param memo1 重量
	 * @param memo2 重量来源 （1：采集、2：人工）
	 * memo3  pk_ask_code 
	 * memo4  pk_ask_desc
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doWeightSave(CommonPage<PlnPicklePlanDetailAndMesPlmD> 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);
		PlnPicklePlanDetail ppp = oci.getObject().getMain();
		
		//验证选中的作业计划主表记录存在
		PlnPicklePlan plp=new PlnPicklePlan();
		plp.setMachine_code(ppp.getMachine_code());
		plp.setPc_plan_no(ppp.getPc_plan_no());
		List<PlnPicklePlan> lplp=this.getMapper(PlnPicklePlanMapper.class).find(plp, 0, 0);
		if(lplp==null||lplp.size()==0){
			rm.setState("500");
			rm.setMsgInfo("选中的作业计划记录不存在");
			return rm;
		}
		//验证选中的作业计划明细表记录存在
		PlnPicklePlanDetail plpd=new PlnPicklePlanDetail();
		plpd.setMachine_code(ppp.getMachine_code());
		plpd.setPc_plan_no(ppp.getPc_plan_no());
		plpd.setObject_no_vt(ppp.getObject_no_vt());
		plpd.setObject_no(ppp.getObject_no());
		List<PlnPicklePlanDetail> lplpd=this.getMapper(PlnPicklePlanDetailMapper.class).find(plpd, 0, 0);
		if(lplpd==null||lplpd.size()==0){
			rm.setState("500");
			rm.setMsgInfo("选中的作业计划明细记录不存在");
			return rm;
		}

		//验证选中的作业计划对应的酸洗主实绩存在
		MesPlmM mcsm=new MesPlmM();
		mcsm.setMachine_code(ppp.getMachine_code());
		mcsm.setSchedule_no(ppp.getPc_plan_no());
		mcsm.setMaterial_no_vt(ppp.getObject_no_vt());
		mcsm.setMaterial_no(ppp.getObject_no());

		List<MesPlmM> lmcsm=this.getMapper(MesPlmMMapper.class).find(mcsm, 0, 0);
		if(lmcsm==null||lmcsm.size()==0){
			rm.setState("500");
			rm.setMsgInfo("["+mcsm.getMaterial_no()+"]酸洗主实绩不存在！");
			return rm;
		}
		if(lmcsm.get(0).getHand_over_status()!=null && !"0".equals(lmcsm.get(0).getHand_over_status())){
			rm.setState("500");
			rm.setMsgInfo("["+mcsm.getMaterial_no_vt()+"]酸洗已生产交工！");
			return rm;
		}
		// 6.、验证原料卷，当前已有出口卷实绩
		MesPlmD mcccd=new MesPlmD();
		mcccd.setProcess_no(lmcsm.get(0).getProcess_no());
		List<MesPlmD> lmcsdxxx =this.getMapper(MesPlmDMapper.class).findWithCondition(mcccd,"coil_no not like '%B'", " coil_no ", 0, 0);
		if(lmcsdxxx==null||lmcsdxxx.size()==0){
			throw new Exception("作业计划原料卷不存在出口卷实绩!");
		}	
		
		//重量
		double sumWeight=Double.parseDouble(oci.getMemo1());
		//验证作业计划原料卷当前勾选选中的出口卷实绩都存在
		for(MesPlmD mcsd:oci.getObject().getChild()){
			//只有一条
			MesPlmD mcsdq=this.getMapper(MesPlmDMapper.class).findById(mcsd.getCoil_no());
			if(mcsdq==null||mcsdq.getCoil_no()==null){
				rm.setState("500");
				rm.setMsgInfo("当前勾选选中的出口卷["+mcsd.getCoil_no()+"]实绩不存在");
				return rm;
			}
		}
		int icount=0;
		String dt=new SimpleDateFormat("yyMMdd").format(now);
		List<MesPlmWgt> lmcw=this.getMapper(MesPlmWgtMapper.class).findWithCondition(null, " substr(serial_no,1,6)='"+dt+"'", " serial_no desc", 0, 1);
		if(lmcw==null||lmcw.size()==0){
			icount=1;
		}else{
			icount=Integer.parseInt(lmcw.get(0).getSerial_no().substring(6,11))+1;
		}
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(userName==null){
			userName="";
		}
		//开始事务：
		//创建酸洗出口卷线上称重实绩记录，即将前端传入的重量信息插入一条记录到MES_CR_SLITTING_WGT表中
		MesPlmWgt mcsw=new MesPlmWgt();
		mcsw.setSerial_no(dt+String.format("%05d", icount++));
		mcsw.setDivide_flag("1");
		mcsw.setDivide_opr(userName);
		mcsw.setDivide_time(now);
		mcsw.setProcess_no(lmcsm.get(0).getProcess_no());
		mcsw.setWgt_source(oci.getMemo2());
		mcsw.setWgt_time(now);
		mcsw.setWgt_value(Double.parseDouble(oci.getMemo1()));
		this.getMapper(MesPlmWgtMapper.class).insert(mcsw);

		MesPlmD mcs=this.getMapper(MesPlmDMapper.class).findById(oci.getObject().getChild().get(0).getCoil_no());
		mcs.setCoil_act_wgt(sumWeight);
		mcs.setCoil_thr_wgt(sumWeight);//酸洗的理重==实重
		mcs.setUpdate_opr(userName);
		mcs.setUpdate_time(now);
		mcs.setCoil_wgt_time(now);//出口卷称重时间
		mcs.setPk_ask_code(oci.getMemo3());
		mcs.setPk_ask_desc(oci.getMemo4());
		this.getMapper(MesPlmDMapper.class).update(mcs);
		//日志
		MesOprLog mol = new MesOprLog("车间MES", "酸洗作业管理", "称重保存", username, opr_time, mcs.getCoil_no(), null, null, null, null);
		this.getMapper(MesOprLogMapper.class).insert(mol);
		rm.setState("200");
		return rm;
	}
	
	
	/**
	 *  同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		检验批号编码规则：炉次号+两位流水号，示例：2619000401）
	 * @param billingList
	 * @return
	 * @throws Exception
	 */
	private Map<String, List<MesPlmD>> groupBillingDataByExcpBatchCode(List<MesPlmD> billingList,String schedule) throws Exception{
		Map<String, List<MesPlmD>> resultMap = new HashMap<String, List<MesPlmD>>();
		try{
			int i=0;
			for(MesPlmD tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"S"+tmExcpNew.getAct_thk()+"S"+tmExcpNew.getAct_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
//					i++;
//					String inspection_lot=schedule+lpad(i+"", 2, "0");
					List<MesPlmD> 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<MesPlmD> tmpList = new ArrayList<MesPlmD>();
					tmpList.add(tmExcpNew);
					resultMap.put(key, tmpList);
				}
 
			}
		}catch(Exception e){
			 System.out.println("炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号进行分组时出现异常");
			 return resultMap;
		}
		return resultMap;
	}
	
	// 补零
	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;
	}
	
	
	
}
