/***文档注释***********************************************
 * 作者            ：
 * 创建日期     ：2018-08-10
 * 描述            ：罩退生产实绩
 * 注意事项     ：
 * 遗留BUG   ：
 * 修改日期     ：
 * 修改人员     ：
 * 修改内容     ：
***********************************************************/
package market.Mes.anneal.impl;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import market.Api.Lms.impl.LmsApiServiceImpl;
import market.Api.Mes.impl.MesApiAnnealPdiPdoImpl;
import market.Api.Mes.impl.MesApiAnnealPlanImpl;
import market.Api.Mes.impl.MesApiDesignInfoImpl;
import market.Api.Mes.impl.Utils;
import market.Api.Qms.impl.QmsApiServiceImpl;
import market.Api.Qms.vo.JudgeResult;
import market.Com.impl.PbModelDbServiceImpl;
import market.Com.mapper.ComBaseInfoMapper;
import market.Com.mapper.ComBaseMachineMapper;
import market.Com.mapper.ComBasePlineMapper;
import market.Com.mapper.ComBaseSteelMapper;
import market.Com.vo.ComBaseCbYdd;
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.mapper.MesCrSlittingDMapper;
import market.Mes.Lengthwise.Performance.mapper.MesCrSlittingMMapper;
import market.Mes.Lengthwise.Performance.vo.MesCrSlittingD;
import market.Mes.Lengthwise.Performance.vo.MesCrSlittingM;
import market.Mes.Lengthwise.Performance.vo.MesPrdDetailReport;
import market.Mes.Lengthwise.Plan.mapper.MesCrCrossCuttingDMapper;
import market.Mes.Lengthwise.Plan.mapper.MesCrCrossCuttingMMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnMaterielDetailMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnProcessPlanMapper;
import market.Mes.Lengthwise.Plan.vo.MesCrCrossCuttingD;
import market.Mes.Lengthwise.Plan.vo.MesCrCrossCuttingM;
import market.Mes.Lengthwise.Plan.vo.PlnMaterielDetail;
import market.Mes.Lengthwise.Plan.vo.PlnProcessPlan;
import market.Mes.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.Rolling.Performance.mapper.MesRcmDMapper;
import market.Mes.Rolling.Performance.mapper.MesRcmMMapper;
import market.Mes.Rolling.Performance.vo.MesRcmD;
import market.Mes.Rolling.Performance.vo.MesRcmM;
import market.Mes.Shift.mapper.MesShiftMMapper;
import market.Mes.Shift.vo.MesShiftM;
import market.Mes.Tpm.mapper.MesTpmDMapper;
import market.Mes.Tpm.mapper.MesTpmMMapper;
import market.Mes.Tpm.vo.MesTpmD;
import market.Mes.Tpm.vo.MesTpmM;
import market.Mes.anneal.mapper.IfBaf01LogMapper;
import market.Mes.anneal.mapper.MesCrAnnealMMapper;
import market.Mes.anneal.mapper.PlnAnnealPlanDetailMapper;
import market.Mes.anneal.mapper.PlnAnnealPlanMapper;
import market.Mes.anneal.service.MesCrAnnealMService;
import market.Mes.anneal.vo.MesCrAnnealM;
import market.Mes.anneal.vo.PlnAnnealPlan;
import market.Mes.anneal.vo.PlnAnnealPlanDetail;
import market.Mes.anneal.vo.PlnAnnealView;
import market.Mes.anneal.vo.PrintLabelView;
import market.Mes.util.DateUtil;
import market.Qms.qcm.service.impl.QcmJhySampleConsignDItemServiceImpl;
import market.Qms.qcm.vo.QcmJhySampleFromPlan;
import market.Slm.FundManagement.impl.SlmFundFirstDetailServiceImpl;
import market.Slm.FundManagement.service.SlmFundFirstDetailService;

import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

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

@RemoteService(path="MesCrAnnealMService")
public class MesCrAnnealMServiceImpl extends BaseServiceImpl<MesCrAnnealM,Object> implements MesCrAnnealMService {
			
	/**memo1:产线代码
	 * @param cp
	 * @return
	 */
	public ResultModel getInspectLotWeb(CommonPage<MesTpmD> cp) {
		ResultModel rm = new ResultModel();
		try {
			if(cp.getObject()==null){
				rm.setState("500");
				rm.setMsgInfo("参数错误");
				return rm;
			}
			MesTpmD object = cp.getObject();
			if(object.getSteel_code()==null || "".equals(object.getSteel_code())){
				rm.setState("500");
				rm.setMsgInfo("牌号为空");
				return rm;
			}
			if(object.getAct_thk()==null || "".equals(object.getAct_thk())){
				rm.setState("500");
				rm.setMsgInfo("厚度为空");
				return rm;
			}
			if(object.getAct_wdt()==null || "".equals(object.getAct_wdt())){
				rm.setState("500");
				rm.setMsgInfo("宽度为空");
				return rm;
			}
			if(object.getCoil_no()==null || "".equals(object.getCoil_no())){
				rm.setState("500");
				rm.setMsgInfo("物料号为空");
				return rm;
			}
			if("C001".equals(cp.getMemo1())){
				MesCrSlittingD mcsd = this.getMapper(MesCrSlittingDMapper.class).findById(object.getCoil_no());
				if(mcsd==null){
					rm.setState("500");
					rm.setMsgInfo("无钢卷信息");
					return rm;
				}
				List<MesCrSlittingM> list_mcs = this.getMapper(MesCrSlittingMMapper.class).findWithCondition(null, "process_no='"+mcsd.getProcess_no()+"'", "", 0, 0);
				if(list_mcs==null || list_mcs.size()<=0){
					rm.setState("500");
					rm.setMsgInfo("暂时生产主实绩信息");
					return rm;
				}
				MesCrSlittingM mes=list_mcs.get(0);
				Map<String, List<MesCrSlittingD>> mc_list =new HashMap<String, List<MesCrSlittingD>>();
		  		if(mes.getSchedule_no()!=null && !"".equals(mes.getSchedule_no())){
		  			List<MesCrSlittingM> v_rec_baf_mList = this.getMapper(MesCrSlittingMMapper.class).findWithCondition(null,"schedule_no='"+mes.getSchedule_no()+"'", null, 0, 0);
		  			List<MesCrSlittingD> mcdlist=new ArrayList<MesCrSlittingD>();
		  			for(MesCrSlittingM mcsttlim:v_rec_baf_mList){
		  				MesCrSlittingD md = this.getMapper(MesCrSlittingDMapper.class).findById(object.getCoil_no());
		  				if(md==null){
		  					rm.setState("500");
							rm.setMsgInfo("暂时生产子卷实绩信息");
							return rm;
		  				}
		  				md.setSteel_code(object.getSteel_code());
		  				md.setAct_thk(object.getAct_thk());
		  				md.setAct_wdt(object.getAct_wdt());
		  				List<MesCrSlittingD> lll = this.getMapper(MesCrSlittingDMapper.class).findWithCondition(null, "process_no='"+mcsttlim.getProcess_no()+"' and coil_no not like '%B'", null, 0, 0);
		  				for(MesCrSlittingD mccc:lll){
		  					if(mccc.getCoil_no().equals(object.getCoil_no())){
		  						mcdlist.add(md);	
		  					}else{
		  						mcdlist.add(mccc);	
		  					}
		  				}
		  			}
		  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
		  						mc_list = groupBillingDataByExcpBatchCode_4mm(mcdlist,mes.getSchedule_no());
		  						
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesCrSlittingD>> grouplist :mc_list.entrySet()){
						List<MesCrSlittingD> listCes = grouplist.getValue();
						for(MesCrSlittingD mcam:listCes){
								if(object.getCoil_no().equals(mcam.getCoil_no())){
									MesCrSlittingD mCrossleo = new MesCrSlittingD();
									mCrossleo.setCoil_no(mcam.getCoil_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesCrSlittingDMapper.class).update(mCrossleo);
									
									rm.setData(mcam.getInspection_lot());
									rm.setMsgInfo("新检验号生成成功");
									rm.setState("200");
									return rm;
								}
								
							}
						}
				}
				
				
			}else if("C002".equals(cp.getMemo1())){
				MesCrSlittingD mcsd = this.getMapper(MesCrSlittingDMapper.class).findById(object.getCoil_no());
				if(mcsd==null){
					rm.setState("500");
					rm.setMsgInfo("无钢卷信息");
					return rm;
				}
				List<MesCrSlittingM> list_mcs = this.getMapper(MesCrSlittingMMapper.class).findWithCondition(null, "process_no='"+mcsd.getProcess_no()+"'", "", 0, 0);
				if(list_mcs==null || list_mcs.size()<=0){
					rm.setState("500");
					rm.setMsgInfo("暂时生产主实绩信息");
					return rm;
				}
				MesCrSlittingM mes=list_mcs.get(0);
				Map<String, List<MesCrSlittingD>> mc_list =new HashMap<String, List<MesCrSlittingD>>();
		  		if(mes.getSchedule_no()!=null && !"".equals(mes.getSchedule_no())){
		  			List<MesCrSlittingM> v_rec_baf_mList = this.getMapper(MesCrSlittingMMapper.class).findWithCondition(null,"schedule_no='"+mes.getSchedule_no()+"'", null, 0, 0);
		  			List<MesCrSlittingD> mcdlist=new ArrayList<MesCrSlittingD>();
		  			for(MesCrSlittingM mcsttlim:v_rec_baf_mList){
		  				MesCrSlittingD md = this.getMapper(MesCrSlittingDMapper.class).findById(object.getCoil_no());
		  				if(md==null){
		  					rm.setState("500");
							rm.setMsgInfo("暂时生产子卷实绩信息");
							return rm;
		  				}
		  				md.setSteel_code(object.getSteel_code());
		  				md.setAct_thk(object.getAct_thk());
		  				md.setAct_wdt(object.getAct_wdt());
		  				List<MesCrSlittingD> lll = this.getMapper(MesCrSlittingDMapper.class).findWithCondition(null, "process_no='"+mcsttlim.getProcess_no()+"' and coil_no not like '%B'", null, 0, 0);
		  				for(MesCrSlittingD mccc:lll){
		  					if(mccc.getCoil_no().equals(object.getCoil_no())){
		  						mcdlist.add(md);	
		  					}else{
		  						mcdlist.add(mccc);	
		  					}
		  				}
		  			}
		  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
		  						mc_list = groupBillingDataByExcpBatchCode_4mm(mcdlist,mes.getSchedule_no());
		  						
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesCrSlittingD>> grouplist :mc_list.entrySet()){
						List<MesCrSlittingD> listCes = grouplist.getValue();
						for(MesCrSlittingD mcam:listCes){
								if(object.getCoil_no().equals(mcam.getCoil_no())){
									MesCrSlittingD mCrossleo = new MesCrSlittingD();
									mCrossleo.setCoil_no(mcam.getCoil_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesCrSlittingDMapper.class).update(mCrossleo);
									
									rm.setData(mcam.getInspection_lot());
									rm.setMsgInfo("新检验号生成成功");
									rm.setState("200");
									return rm;
								}
								
							}
						}
				}
			}else if("C011".equals(cp.getMemo1())){
				MesTpmD mcsd = this.getMapper(MesTpmDMapper.class).findById(object.getCoil_no());
				if(mcsd==null){
					rm.setState("500");
					rm.setMsgInfo("无钢卷信息");
					return rm;
				}
				List<MesTpmM> list_mcs = this.getMapper(MesTpmMMapper.class).findWithCondition(null, "material_no='"+mcsd.getMaterial_no()+"' and schedule_no='"+mcsd.getSchedule_no()+"'", "", 0, 0);
				if(list_mcs==null || list_mcs.size()<=0){
					rm.setState("500");
					rm.setMsgInfo("暂时生产主实绩信息");
					return rm;
				}
				MesTpmM mes=list_mcs.get(0);
				Map<String, List<MesTpmD>> mc_list =new HashMap<String, List<MesTpmD>>();
		  		if(mes.getSchedule_no()!=null && !"".equals(mes.getSchedule_no())){
		  			List<MesTpmM> v_rec_baf_mList = this.getMapper(MesTpmMMapper.class).findWithCondition(null,"schedule_no='"+mes.getSchedule_no()+"'", null, 0, 0);
		  			List<MesTpmD> mcdlist=new ArrayList<MesTpmD>();
		  			for(MesTpmM mcsttlim:v_rec_baf_mList){
		  				MesTpmD md = this.getMapper(MesTpmDMapper.class).findById(object.getCoil_no());
		  				if(md==null){
		  					rm.setState("500");
							rm.setMsgInfo("暂时生产子卷实绩信息");
							return rm;
		  				}
		  				md.setSteel_code(object.getSteel_code());
		  				md.setAct_thk(object.getAct_thk());
		  				md.setAct_wdt(object.getAct_wdt());
		  				List<MesTpmD> lll = this.getMapper(MesTpmDMapper.class).findWithCondition(null, "schedule_no='"+mcsttlim.getSchedule_no()+"' and material_no='"+mcsttlim.getMaterial_no()+"' and coil_no not like '%B'", null, 0, 0);
		  				for(MesTpmD mccc:lll){
		  					if(mccc.getCoil_no().equals(object.getCoil_no())){
		  						mcdlist.add(md);	
		  					}else{
		  						mcdlist.add(mccc);	
		  					}
		  				}
		  			}
		  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
		  						mc_list = groupBillingDataByExcpBatchCode_tpm(mcdlist,mes.getSchedule_no());
		  						
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesTpmD>> grouplist :mc_list.entrySet()){
						List<MesTpmD> listCes = grouplist.getValue();
						for(MesTpmD mcam:listCes){
								if(object.getCoil_no().equals(mcam.getCoil_no())){
									MesTpmD mCrossleo = new MesTpmD();
									mCrossleo.setCoil_no(mcam.getCoil_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesTpmDMapper.class).update(mCrossleo);
									
									rm.setData(mcam.getInspection_lot());
									rm.setMsgInfo("新检验号生成成功");
									rm.setState("200");
									return rm;
								}
								
							}
						}
				}
				
			}else if("C012".equals(cp.getMemo1())){
				MesCrCrossCuttingD mcsd = this.getMapper(MesCrCrossCuttingDMapper.class).findById(object.getCoil_no());
				if(mcsd==null){
					rm.setState("500");
					rm.setMsgInfo("无钢卷信息");
					return rm;
				}
				List<MesCrCrossCuttingM> list_mcs = this.getMapper(MesCrCrossCuttingMMapper.class).findWithCondition(null, "process_no='"+mcsd.getProcess_no()+"'", "", 0, 0);
				if(list_mcs==null || list_mcs.size()<=0){
					rm.setState("500");
					rm.setMsgInfo("暂时生产主实绩信息");
					return rm;
				}
				MesCrCrossCuttingM mes=list_mcs.get(0);
				Map<String, List<MesCrCrossCuttingD>> mc_list =new HashMap<String, List<MesCrCrossCuttingD>>();
		  		if(mes.getSchedule_no()!=null && !"".equals(mes.getSchedule_no())){
		  			List<MesCrCrossCuttingM> v_rec_baf_mList = this.getMapper(MesCrCrossCuttingMMapper.class).findWithCondition(null,"schedule_no='"+mes.getSchedule_no()+"'", null, 0, 0);
		  			List<MesCrCrossCuttingD> mcdlist=new ArrayList<MesCrCrossCuttingD>();
		  			for(MesCrCrossCuttingM mcsttlim:v_rec_baf_mList){
		  				MesCrCrossCuttingD md = this.getMapper(MesCrCrossCuttingDMapper.class).findById(object.getCoil_no());
		  				if(md==null){
		  					rm.setState("500");
							rm.setMsgInfo("暂时生产子卷实绩信息");
							return rm;
		  				}
		  				md.setSteel_code(object.getSteel_code());
		  				md.setAct_thk(object.getAct_thk());
		  				md.setAct_wdt(object.getAct_wdt());
		  				List<MesCrCrossCuttingD> lll = this.getMapper(MesCrCrossCuttingDMapper.class).findWithCondition(null, "process_no='"+mcsttlim.getProcess_no()+"' and coil_no not like '%B'", null, 0, 0);
		  				for(MesCrCrossCuttingD mccc:lll){
		  					if(mccc.getPacking_no().equals(object.getCoil_no())){
		  						mcdlist.add(md);	
		  					}else{
		  						mcdlist.add(mccc);	
		  					}
		  				}
		  			}
		  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
		  						mc_list = groupBillingDataByExcpBatchCode_3mm(mcdlist,mes.getSchedule_no());
		  						
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesCrCrossCuttingD>> grouplist :mc_list.entrySet()){
						List<MesCrCrossCuttingD> listCes = grouplist.getValue();
						for(MesCrCrossCuttingD mcam:listCes){
								if(object.getCoil_no().equals(mcam.getPacking_no())){
									MesCrCrossCuttingD mCrossleo = new MesCrCrossCuttingD();
									mCrossleo.setPacking_no(mcam.getPacking_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesCrCrossCuttingDMapper.class).update(mCrossleo);
									
									rm.setData(mcam.getInspection_lot());
									rm.setMsgInfo("新检验号生成成功");
									rm.setState("200");
									return rm;
								}
								
							}
						}
				}
		  		
			}else if("C016".equals(cp.getMemo1())){
				MesRcmD mcsd = this.getMapper(MesRcmDMapper.class).findById(object.getCoil_no());
				if(mcsd==null){
					rm.setState("500");
					rm.setMsgInfo("无钢卷信息");
					return rm;
				}
				List<MesRcmM> list_mcs = this.getMapper(MesRcmMMapper.class).findWithCondition(null, "process_no='"+mcsd.getProcess_no()+"'", "", 0, 0);
				
				if(list_mcs==null || list_mcs.size()<=0){
					rm.setState("500");
					rm.setMsgInfo("暂时生产主实绩信息");
					return rm;
				}
				MesRcmM mes=list_mcs.get(0);
				Map<String, List<MesRcmD>> mc_list =new HashMap<String, List<MesRcmD>>();
		  		if(mes.getSchedule_no()!=null && !"".equals(mes.getSchedule_no())){
		  			List<MesRcmM> v_rec_baf_mList = this.getMapper(MesRcmMMapper.class).findWithCondition(null,"schedule_no='"+mes.getSchedule_no()+"'", null, 0, 0);
		  			List<MesRcmD> mcdlist=new ArrayList<MesRcmD>();
		  			for(MesRcmM mcsttlim:v_rec_baf_mList){
		  				MesRcmD md = this.getMapper(MesRcmDMapper.class).findById(object.getCoil_no());
		  				if(md==null){
		  					rm.setState("500");
							rm.setMsgInfo("暂时生产子卷实绩信息");
							return rm;
		  				}
		  				md.setSteel_code(object.getSteel_code());
		  				md.setAct_thk(object.getAct_thk());
		  				md.setAct_wdt(object.getAct_wdt());
		  				List<MesRcmD> lll = this.getMapper(MesRcmDMapper.class).findWithCondition(null, "process_no='"+mcsttlim.getProcess_no()+"' and coil_no not like '%B'", null, 0, 0);
		  				for(MesRcmD mccc:lll){
		  					if(mccc.getCoil_no().equals(object.getCoil_no())){
		  						mcdlist.add(md);	
		  					}else{
		  						mcdlist.add(mccc);	
		  					}
		  				}
		  			}
		  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0 && mcdlist.size()>0){
		  						mc_list = groupBillingDataByExcpBatchCode_rcm(mcdlist,mes.getSchedule_no());
		  						
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesRcmD>> grouplist :mc_list.entrySet()){
						List<MesRcmD> listCes = grouplist.getValue();
						for(MesRcmD mcam:listCes){
								if(object.getCoil_no().equals(mcam.getCoil_no())){
									MesRcmD mCrossleo = new MesRcmD();
									mCrossleo.setCoil_no(mcam.getCoil_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesRcmDMapper.class).update(mCrossleo);
									
									rm.setData(mcam.getInspection_lot());
									rm.setMsgInfo("新检验号生成成功");
									rm.setState("200");
									return rm;
								}
								
							}
						}
				}
		  		
			}else if("C013".equals(cp.getMemo1()) || "C014".equals(cp.getMemo1())
					|| "C015".equals(cp.getMemo1()) || "C017".equals(cp.getMemo1())){
				
				/*
		  		检验批分批规则：
		  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
		  		 */
				List<MesCrAnnealM> list_mcs = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null, "coil_no='"+object.getCoil_no()+"'", "", 0, 0);
				if(list_mcs==null || list_mcs.size()<=0){
					rm.setState("500");
					rm.setMsgInfo("暂时生产主实绩信息");
					return rm;
				}
				MesCrAnnealM mes=list_mcs.get(0);
			    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
		  		if(mes.getBatch_no()!=null && !"".equals(mes.getBatch_no())){
		  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+mes.getBatch_no()+"'", null, 0, 0);
		  			mes.setSteel_code(object.getSteel_code());
		  			mes.setAct_thk(object.getAct_thk());
		  			mes.setAct_wdt(object.getAct_wdt());
		  			List<MesCrAnnealM> v_rec_baf_list=new ArrayList<>();
	  				for(MesCrAnnealM mccc:v_rec_baf_mList){
	  					if(mccc.getCoil_no().equals(object.getCoil_no())){
	  						v_rec_baf_list.add(mes);	
	  					}else{
	  						v_rec_baf_list.add(mccc);	
	  					}
	  				}
		  			if(v_rec_baf_list!=null && v_rec_baf_list.size()>0){
		  					try{
		  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_list);
		  					}catch(Exception e){
		  						
		  					}
		  			}
		  		}
		  		if(mc_list!=null && mc_list.size()>0){
					for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
						String key = grouplist.getKey();
						List<MesCrAnnealM> listCes = grouplist.getValue();
						for(MesCrAnnealM mcam:listCes){
							String anm_key=mes.getSteel_code()+"T"+mes.getMtr_thk()+"T"+mes.getMtr_wdt();
							if(anm_key.equals(key) && mes.getMaterial_no().equals(mcam.getMaterial_no())){
								mes.setInspection_lot(mcam.getInspection_lot());
								MesCrAnnealM mCrossleo = new MesCrAnnealM();
								//mCrossleo.setMachine_code(sum.getMemo1());
								mCrossleo.setSchedule_no(mcam.getSchedule_no());
								//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
								mCrossleo.setMaterial_no(mcam.getMaterial_no());
								mCrossleo.setInspection_lot(mcam.getInspection_lot());
								this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
								rm.setData(mcam.getInspection_lot());
								rm.setMsgInfo("新检验号生成成功");
								rm.setState("200");
								return rm;
							}
						}
					}
				}
			}
			rm.setState("200");
		} catch (Exception ex) {
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!" + ex.getMessage());
		}
		return rm;
	}
	
	
	/**
	 *  同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		检验批号编码规则：炉次号+两位流水号，示例：2619000401）
	 * @param billingList
	 * @return
	 * @throws Exception
	 */
	private Map<String, List<MesRcmD>> groupBillingDataByExcpBatchCode_rcm(List<MesRcmD> billingList,String schedule) throws Exception{
		Map<String, List<MesRcmD>> resultMap = new HashMap<String, List<MesRcmD>>();
		try{
			int i=0;
			Integer max=this.getMapper(MesCrAnnealMMapper.class).findMaxInsrcm(schedule);
			if(max!=null){
				i=max;
			}
			for(MesRcmD tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"L"+tmExcpNew.getAct_thk()+"L"+tmExcpNew.getAct_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
//					i++;
//					String inspection_lot=schedule+lpad(i+"", 2, "0");
					List<MesRcmD> 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<MesRcmD> tmpList = new ArrayList<MesRcmD>();
					tmpList.add(tmExcpNew);
					resultMap.put(key, tmpList);
				}
 
			}
		}catch(Exception e){
			 System.out.println("炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号进行分组时出现异常");
			 return resultMap;
		}
		return resultMap;
	}
	
	
	/**
	 *  同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		检验批号编码规则：炉次号+两位流水号，示例：2619000401）
	 * @param billingList
	 * @return
	 * @throws Exception
	 */
	private Map<String, List<MesCrCrossCuttingD>> groupBillingDataByExcpBatchCode_3mm(List<MesCrCrossCuttingD> billingList,String schedule) throws Exception{
		Map<String, List<MesCrCrossCuttingD>> resultMap = new HashMap<String, List<MesCrCrossCuttingD>>();
		try{
			int i=0;
			Integer max=this.getMapper(MesCrAnnealMMapper.class).findMaxIns3mm(schedule);
			if(max!=null){
				i=max;
			}
			for(MesCrCrossCuttingD tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"K"+tmExcpNew.getAct_thk()+"K"+tmExcpNew.getAct_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
//					i++;
//					String inspection_lot=schedule+lpad(i+"", 2, "0");
					List<MesCrCrossCuttingD> list = resultMap.get(key);
					if(list!=null && list.size()>0){
						tmExcpNew.setInspection_lot(list.get(0).getInspection_lot());
					}
					resultMap.get(key).add(tmExcpNew);
				}else{//map中不存在，新建key，用来存放数据
					i++;
					String inspection_lot=schedule+lpad(i+"", 2, "0");
					tmExcpNew.setInspection_lot(inspection_lot);
					List<MesCrCrossCuttingD> tmpList = new ArrayList<MesCrCrossCuttingD>();
					tmpList.add(tmExcpNew);
					resultMap.put(key, tmpList);
				}
 
			}
		}catch(Exception e){
			 System.out.println("炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号进行分组时出现异常");
			 return resultMap;
		}
		return resultMap;
	}
	
	/**
	 *  同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		检验批号编码规则：炉次号+两位流水号，示例：2619000401）
	 * @param billingList
	 * @return
	 * @throws Exception
	 */
	private Map<String, List<MesTpmD>> groupBillingDataByExcpBatchCode_tpm(List<MesTpmD> billingList,String schedule) throws Exception{
		Map<String, List<MesTpmD>> resultMap = new HashMap<String, List<MesTpmD>>();
		try{
			int i=0;
			Integer max=this.getMapper(MesCrAnnealMMapper.class).findMaxInstpm(schedule);
			if(max!=null){
				i=max;
			}
			for(MesTpmD tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"P"+tmExcpNew.getAct_thk()+"P"+tmExcpNew.getAct_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
					List<MesTpmD> 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<MesTpmD> tmpList = new ArrayList<MesTpmD>();
					tmpList.add(tmExcpNew);
					resultMap.put(key, tmpList);
				} 
			}
		}catch(Exception e){
			 System.out.println("炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号进行分组时出现异常");
			 return resultMap;
		}
		return resultMap;
	}
	
	
	private Map<String, List<MesCrSlittingD>> groupBillingDataByExcpBatchCode_4mm(List<MesCrSlittingD> billingList,String schedule) throws Exception{
		Map<String, List<MesCrSlittingD>> resultMap = new HashMap<String, List<MesCrSlittingD>>();
		try{
			int i=0;
			Integer max=this.getMapper(MesCrAnnealMMapper.class).findMaxIns4mm(schedule);
			if(max!=null){
				i=max;
			}
			for(MesCrSlittingD tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"F"+tmExcpNew.getAct_thk()+"F"+tmExcpNew.getAct_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
					List<MesCrSlittingD> 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<MesCrSlittingD> tmpList = new ArrayList<MesCrSlittingD>();
					tmpList.add(tmExcpNew);
					resultMap.put(key, tmpList);
				}
			}
		}catch(Exception e){
			 System.out.println("炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号进行分组时出现异常");
			 return resultMap;
		}
		return resultMap;
	}	
	
	/**
	 * 退火炉机组生产明细报表
	 * memo1:机台代码
	 * startTime:计划下发时间开始
	 * endTime:计划下发时间结束
	 * startTime2:交工时间开始
	 * endTime2:交工时间结束
	 * memo2:生产时间开始
	 * meme3:生产时间结束
	 * memo4:交货时间开始
	 * memo5:交货时间结束
	 * */
	public ResultModel doPrdDetailWeb_tuihuo(CommonPage<MesPrdDetailReport> oci){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.class).doPrdDetailWeb_tuihuo(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 doProductionSteelReportWeb(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.class).doProductionSteelReport(oci.getObject()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}	
	
	/**
	 * 生产监视页面接口
	 * @param oci
	 * memo1:传机台代码
	 * memo2:传机台代码【如果有南方D,和南方G的，这里需要传机台代码】
	 * @return
	 */
	public ResultModel doQueryTrcWeb(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		if("".equals(oci.getMemo2())){
			oci.setMemo2(null);
		}
		try{
			List<MesCrAnnealM> lpav=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb7(oci.getMemo1(),oci.getMemo2());
			for(MesCrAnnealM pav:lpav){
				String i="";
				i=pav.getStatus()==null?"":pav.getStatus();
				switch(i){
		        case "01":
		            pav.setStatus_desc("上炉台");break;
		        case "02":
		            pav.setStatus_desc("扣加热罩");break;
		        case "03":
		            pav.setStatus_desc("加热开始");break;
		        case "04":
		            pav.setStatus_desc("加热结束");break;
		        case "05":
		            pav.setStatus_desc("带罩冷却开始");break;
		        case "06":
		            pav.setStatus_desc("带罩冷却结束");break;
		        case "07":
		            pav.setStatus_desc("风冷开始");break;
		        case "08":
		            pav.setStatus_desc("风冷结束");break;
		        case "09":
		            pav.setStatus_desc("水冷开始");break;
		        case "10":
		            pav.setStatus_desc("水冷结束");break;
		        case "11":
		            pav.setStatus_desc("出炉/上终冷台");break;
		        case "12":
		            pav.setStatus_desc("下终冷台");break;
		        case "00":
		            pav.setStatus_desc("组垛完成");break;
		        default:
		        	pav.setStatus_desc(pav.getStatus_desc());break;
		        }
			}
			rm.setData(lpav);
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**
	 * memo1:机台代码  V_MCH_CODE
	 * 动作处理_自动定位按钮
	 * 展示到“罩退作业计划”表格：宝信退火炉，艾伯纳退火炉
	 * */
	public ResultModel doQueryWeb(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			List<PlnAnnealView> lpav = this.getMapper(MesCrAnnealMMapper.class).doQueryWeb(oci.getMemo1());
			for(PlnAnnealView pav:lpav){
				String i = pav.getStatus()==null?"":pav.getStatus();
				switch(i){
		        case "5BAN01":
		            pav.setStatus_desc("计划已编制");break;
		        case "5BAN02":
		            pav.setStatus_desc("已下发");break;
		        case "5BAN03":
		            pav.setStatus_desc("开始作业");break;
		        case "5BAN05":
		            pav.setStatus_desc("正在作业");break;
		        case "5BAN11":
		            pav.setStatus_desc("上炉台");break;
		        case "5BAN12":
		            pav.setStatus_desc("扣加热罩");break;
		        case "5BAN13":
		            pav.setStatus_desc("加热开始");break;
		        case "5BAN20":
		            pav.setStatus_desc("加热结束");break;
		        case "5BAN23":
		            pav.setStatus_desc("带罩冷却开始");break;
		        case "5BAN30":
		            pav.setStatus_desc("带罩冷却结束");break;
		        case "5BAN33":
		            pav.setStatus_desc("风冷开始");break;
		        case "5BAN40":
		            pav.setStatus_desc("风冷结束");break;
		        case "5BAN43":
		            pav.setStatus_desc("水冷开始");break;
		        case "5BAN50":
		            pav.setStatus_desc("水冷结束");break;
		        case "5BAN53":
		            pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN60":
		        	pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN70":
		        	pav.setStatus_desc("组垛完成");break;
		        case "5BAN80":
		        	pav.setStatus_desc("作业完成");break;
		        default:
		        	pav.setStatus_desc(pav.getStatus());break;
		        }
			}
			rm.setData(lpav);
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**
	 * 南方D,南方G退火炉
	 * memo1:机台代码  V_MCH_CODE
	 * 动作处理_自动定位按钮
	 * 展示到“罩退作业计划”表格
	 * */
	public ResultModel doQueryWeb_DG(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			List<PlnAnnealView> lpav = this.getMapper(MesCrAnnealMMapper.class).doQueryWeb_DG(oci.getMemo1());
			for(PlnAnnealView pav:lpav){
				String i = pav.getStatus()==null?"":pav.getStatus();
				switch(i){
		        case "5BAN01":
		            pav.setStatus_desc("计划已编制");break;
		        case "5BAN02":
		            pav.setStatus_desc("已下发");break;
		        case "5BAN03":
		            pav.setStatus_desc("开始作业");break;
		        case "5BAN05":
		            pav.setStatus_desc("正在作业");break;
		        case "5BAN11":
		            pav.setStatus_desc("上炉台");break;
		        case "5BAN12":
		            pav.setStatus_desc("扣加热罩");break;
		        case "5BAN13":
		            pav.setStatus_desc("加热开始");break;
		        case "5BAN20":
		            pav.setStatus_desc("加热结束");break;
		        case "5BAN23":
		            pav.setStatus_desc("带罩冷却开始");break;
		        case "5BAN30":
		            pav.setStatus_desc("带罩冷却结束");break;
		        case "5BAN33":
		            pav.setStatus_desc("风冷开始");break;
		        case "5BAN40":
		            pav.setStatus_desc("风冷结束");break;
		        case "5BAN43":
		            pav.setStatus_desc("水冷开始");break;
		        case "5BAN50":
		            pav.setStatus_desc("水冷结束");break;
		        case "5BAN53":
		            pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN60":
		        	pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN70":
		        	pav.setStatus_desc("组垛完成");break;
		        case "5BAN80":
		        	pav.setStatus_desc("作业完成");break;
		        default:
		        	pav.setStatus_desc(pav.getStatus());break;
		        }
			}
			rm.setData(lpav);
			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<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.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;
	}
	
	
	/**
	 * 展示到“当班汇总信息”区域
	 * V_MCH_CODE（机台代码）、V_WRK_DATE（登录日期）、V_WRK_ORD（登录班次）、V_WRK_GRP（登录班组）
	 * memo1-4
	 * @param oci
	 * @return
	 */
	public ResultModel doQueryWrkWeb_DG(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.class).doQueryWrkWeb_DG(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<MesCrAnnealM> cp){
		ResultModel rm=new ResultModel();
		try{
			List<PlnAnnealView> lpav = this.getMapper(MesCrAnnealMMapper.class).doQueryWeb2(cp.getMemo1(),cp.getStartTime(),cp.getEndTime(),cp.getMemo2(),cp.getMemo3());
			for(PlnAnnealView pav:lpav){
				String i = pav.getStatus()==null?"":pav.getStatus();
				switch(i){
		        case "5BAN01":
		            pav.setStatus_desc("计划已编制");break;
		        case "5BAN02":
		            pav.setStatus_desc("已下发");break;
		        case "5BAN03":
		            pav.setStatus_desc("开始作业");break;
		        case "5BAN05":
		            pav.setStatus_desc("正在作业");break;
		        case "5BAN11":
		            pav.setStatus_desc("上炉台");break;
		        case "5BAN12":
		            pav.setStatus_desc("扣加热罩");break;
		        case "5BAN13":
		            pav.setStatus_desc("加热开始");break;
		        case "5BAN20":
		            pav.setStatus_desc("加热结束");break;
		        case "5BAN23":
		            pav.setStatus_desc("带罩冷却开始");break;
		        case "5BAN30":
		            pav.setStatus_desc("带罩冷却结束");break;
		        case "5BAN33":
		            pav.setStatus_desc("风冷开始");break;
		        case "5BAN40":
		            pav.setStatus_desc("风冷结束");break;
		        case "5BAN43":
		            pav.setStatus_desc("水冷开始");break;
		        case "5BAN50":
		            pav.setStatus_desc("水冷结束");break;
		        case "5BAN53":
		            pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN60":
		        	pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN70":
		        	pav.setStatus_desc("组垛完成");break;
		        case "5BAN80":
		        	pav.setStatus_desc("作业完成");break;
		        default:
		        	pav.setStatus_desc(pav.getStatus());break;
		        }			
			}
			rm.setData(lpav);
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**
	 * 南方D，南方G
	    动作处理_查询按钮
	 memo1:机台代码
	 memo2：作业计划号
	 memo3:原料卷号
	 startTime：开始时间
	 endTime：结束时间
	* @param oci
	* @return
	*/
	public ResultModel doQueryWeb2_DG(CommonPage<MesCrAnnealM> cp){
		ResultModel rm=new ResultModel();
		try{
			List<PlnAnnealView> lpav = this.getMapper(MesCrAnnealMMapper.class).doQueryWeb2_DG(cp.getMemo1(),cp.getStartTime(),cp.getEndTime(),cp.getMemo2(),cp.getMemo3());
			for(PlnAnnealView pav:lpav){
				String i = pav.getStatus()==null?"":pav.getStatus();
				switch(i){
		        case "5BAN01":
		            pav.setStatus_desc("计划已编制");break;
		        case "5BAN02":
		            pav.setStatus_desc("已下发");break;
		        case "5BAN03":
		            pav.setStatus_desc("开始作业");break;
		        case "5BAN05":
		            pav.setStatus_desc("正在作业");break;
		        case "5BAN11":
		            pav.setStatus_desc("上炉台");break;
		        case "5BAN12":
		            pav.setStatus_desc("扣加热罩");break;
		        case "5BAN13":
		            pav.setStatus_desc("加热开始");break;
		        case "5BAN20":
		            pav.setStatus_desc("加热结束");break;
		        case "5BAN23":
		            pav.setStatus_desc("带罩冷却开始");break;
		        case "5BAN30":
		            pav.setStatus_desc("带罩冷却结束");break;
		        case "5BAN33":
		            pav.setStatus_desc("风冷开始");break;
		        case "5BAN40":
		            pav.setStatus_desc("风冷结束");break;
		        case "5BAN43":
		            pav.setStatus_desc("水冷开始");break;
		        case "5BAN50":
		            pav.setStatus_desc("水冷结束");break;
		        case "5BAN53":
		            pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN60":
		        	pav.setStatus_desc("出炉/上终冷台");break;
		        case "5BAN70":
		        	pav.setStatus_desc("组垛完成");break;
		        case "5BAN80":
		        	pav.setStatus_desc("作业完成");break;
		        default:
		        	pav.setStatus_desc(pav.getStatus());break;
		        }
			}
			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<MesCrAnnealM> cp){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.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;
	}
	
	/**
	 * 动作处理_下发PDI
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 * */
	public ResultModel doSendAnnealPDI(CommonPage<PlnAnnealPlan> 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;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return rm;
			}
		}		
		List<String> list_v_message=new ArrayList<>();
		// (2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			String v_message="";
			try{
				v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).SendBaf01Pdi(sum.getMemo1(),plp.getAn_plan_no(),plp.getObject_no_vt(),
						plp.getMaterial_no(),username,v_message);
			}catch(Exception e){
				e.printStackTrace();
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message=e.getMessage().substring(0,200);
				}else{
					v_message=e.getMessage();
				}
			}
			v_message="计划号{"+plp.getAn_plan_no()+"}"+"虚拟卷号{" +plp.getObject_no_vt()+"}"+"原料卷号{" +plp.getMaterial_no()+"}"+v_message;	
			list_v_message.add(v_message);
		}
		StringBuilder sb=new StringBuilder();
		// --(3)、写接口日志：与业务处理分开，单独的事务
		for(String s:list_v_message){
			try{
				this.getMapper(IfBaf01LogMapper.class).doInsert("","SendBaf01Pdi","",s);
			}catch(Exception e){
				e.printStackTrace();
			}
			sb.append(s+"<br>");
		}
		//日志
		for(PlnAnnealPlan pap: sum.getObjectList()){			
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "下发PDI", username, opr_time, pap.getMaterial_no(), null, null, null, (("M0004".equals(pap.getMachine_code()))?"宝信退火炉":"艾伯纳退火炉"));
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		rm.setMsgInfo(sb.toString());
		rm.setState("200");
		return rm;
	}
	
	/**
	 * 动作处理_下发PDI
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	   machine_code 机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 * */
	public ResultModel doSendAnnealPDI_DG(CommonPage<PlnAnnealPlan> 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.getObjectList()==null || sum.getObjectList().size()<=0){
			rm.setState("500");
			rm.setMsgInfo("参数错误：未指定需要下发PDI的原料卷信息！");
			return rm;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：机台代码不能为空！");
				return rm;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return rm;
			}
		}
		
		List<String> list_v_message=new ArrayList<>();
		//(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			String v_message="";
			try{
				v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).SendBaf01Pdi(plp.getMachine_code(),plp.getAn_plan_no(),plp.getObject_no_vt(),
						plp.getMaterial_no(),username,v_message);
			}catch(Exception e){
				e.printStackTrace();
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message=e.getMessage().substring(0,200);
				}else{
					v_message=e.getMessage();
				}
			}
			v_message="计划号{"+plp.getAn_plan_no()+"}"+"虚拟卷号{" +plp.getObject_no_vt()+"}"+"原料卷号{" +plp.getMaterial_no()+"}"+v_message;	
			list_v_message.add(v_message);
		}
		StringBuilder sb=new StringBuilder();
		// --(3)、写接口日志：与业务处理分开，单独的事务
		for(String s:list_v_message){
			try{
				this.getMapper(IfBaf01LogMapper.class).doInsert("","SendBaf01Pdi","",s);
			}catch(Exception e){
				e.printStackTrace();
			}
			sb.append(s+"<br>");
		}
		//日志
		for(PlnAnnealPlan plp: sum.getObjectList()){			
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "下发PDI", username, opr_time, plp.getMaterial_no(), null, null, null, "南方退火炉");
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		rm.setMsgInfo(sb.toString());
		rm.setState("200");
		return rm;
	}
	
	
	
	
	/**
	 * 动作处理_撤销PDI
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 * */
	public ResultModel doCancelAnnealPDI(CommonPage<PlnAnnealPlan> 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;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return rm;
			}
		}		
		List<String> list_v_message=new ArrayList<>();
		//--(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			String v_message="";
			try{
				v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).L3RevokeBaf01Pdi(sum.getMemo1(),plp.getAn_plan_no(),plp.getObject_no_vt(),
						plp.getMaterial_no(),username,v_message);
			}catch(Exception e){
				e.printStackTrace();
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message=e.getMessage().substring(0,200);
				}else{
					v_message=e.getMessage();
				}
			}
			v_message="计划号{"+plp.getAn_plan_no()+"}"+"虚拟卷号{" +plp.getObject_no_vt()+"}"+"原料卷号{" +plp.getMaterial_no()+"}"+v_message;	
			list_v_message.add(v_message);
		}
		StringBuilder sb=new StringBuilder();
		// --(3)、写接口日志：与业务处理分开，单独的事务
		for(String s:list_v_message){
			try{
				this.getMapper(IfBaf01LogMapper.class).doInsert("","L3RevokeBaf01Pdi","",s);
			}catch(Exception e){
				e.printStackTrace();
			}
			sb.append(s+"<br>");
		}
		//日志
		for(PlnAnnealPlan pap: sum.getObjectList()){			
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "撤销PDI", username, opr_time, pap.getMaterial_no(), null, null, null, (("M0004".equals(pap.getMachine_code()))?"宝信退火炉":"艾伯纳退火炉"));
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		rm.setMsgInfo(sb.toString());
		rm.setState("200");
		return rm;
	}
	
	
	/**
	 * 动作处理_撤销PDI
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * machine_code 机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 * */
	public ResultModel doCancelAnnealPDI_DG(CommonPage<PlnAnnealPlan> 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.getObjectList()==null || sum.getObjectList().size()<=0){
			rm.setState("500");
			rm.setMsgInfo("参数错误：未指定需要撤销下发PDI的原料卷信息！");
			return rm;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：机台代码不能为空！");
				return rm;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				rm.setState("500");
				rm.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return rm;
			}
		}		
		List<String> list_v_message=new ArrayList<>();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		if(userName==null){
			userName="";
		}
		//--(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			String v_message="";
			try{
				v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).L3RevokeBaf01Pdi(plp.getMachine_code(),plp.getAn_plan_no(),plp.getObject_no_vt(),
						plp.getMaterial_no(),userName,v_message);
			}catch(Exception e){
				e.printStackTrace();
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message=e.getMessage().substring(0,200);
				}else{
					v_message=e.getMessage();
				}
			}
			v_message="计划号{"+plp.getAn_plan_no()+"}"+"虚拟卷号{" +plp.getObject_no_vt()+"}"+"原料卷号{" +plp.getMaterial_no()+"}"+v_message;	
			list_v_message.add(v_message);
		}
		StringBuilder sb=new StringBuilder();
		// --(3)、写接口日志：与业务处理分开，单独的事务
		for(String s:list_v_message){
			try{
				this.getMapper(IfBaf01LogMapper.class).doInsert("","L3RevokeBaf01Pdi","",s);
			}catch(Exception e){
				e.printStackTrace();
			}
			sb.append(s+"<br>");
		}
		//日志
		for(PlnAnnealPlan plp: sum.getObjectList()){
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "撤销PDI", username, opr_time, plp.getMaterial_no(), null, null, null, "南方退火炉");
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		rm.setMsgInfo(sb.toString());
		rm.setState("200");
		return rm;
	}
	
	
	
	/***
	 * 动作处理-上料按钮     
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1：机台代码，
	 * memo2：登录班组，
	 * memo3:登录用户名
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doAnnealInsWeb(CommonPage<PlnAnnealPlan> 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);
		
		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;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要上料的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				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;
		}
		//  --（3）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		String dbTime=rmDb.getData().toString().substring(11);
		String wrk_date=null,wrk_ord=null,wrk_grp=null;
		if("200".equals(rmDb.getState())){
			dbTime=rmDb.getData().toString().substring(11);
			wrk_date=rmDb.getData().toString().substring(0,10);			
			if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
				wrk_ord="1";
			}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
				wrk_ord="2";
			}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
				wrk_ord="1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date;
				try {
					date = formatYmd.parse(wrk_date);
				} catch (Exception e) {
					throw new Exception("获取数据库时间失败，请稍后重试");
				}
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
				wrk_date=formatYmd.format(c.getTime());
			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}
		// （3.4）、根据计算的日期班次，获取交接班记录的班组
		MesShiftM msm=new MesShiftM();
		if(sum.getMemo1().equals("M0009")){
			msm.setMachine_code("M0005");
		}else{
			msm.setMachine_code(sum.getMemo1());
		}
		msm.setWrk_date(wrk_date);
		msm.setWrk_ord(wrk_ord);
		v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
		if(v_cnt<=0){
			wrk_grp=sum.getMemo2();//   --暂无交接班记录，则使用前端传入的班组代码
		}else{
			//    --否则获取交接班记录中的班组
			List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
			wrk_grp=lmsm.get(0).getWrk_grp();
		}
		//  --(4)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			//    --(4.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(sum.getMemo1());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(4.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(sum.getMemo1());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
						+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
			}
			PlnAnnealPlanDetail cuttdel = new PlnAnnealPlanDetail();
			cuttdel.setMachine_code(sum.getMemo1());
			cuttdel.setAn_plan_no(plp.getAn_plan_no());
			cuttdel.setObject_no_vt(plp.getObject_no_vt());
			cuttdel.setObject_no(plp.getMaterial_no());
			List<PlnAnnealPlanDetail> v_rec_pln_d = this.getMapper(PlnAnnealPlanDetailMapper.class).findWithCondition(cuttdel, null, null, 0, 0);
			//2018-11-29 只有是已下发状态的钢卷才能下发
			if(v_rec_pln_d!=null && v_rec_pln_d.size()>0){
				if(!"5BAN02".equals(v_rec_pln_d.get(0).getStatus())){
					throw new Exception("当前状态{"+v_rec_pln_d.get(0).getStatus()+"}不为已下发");
				}
			}
			//(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)、验证指定的计划，还未创建罩退作业主实绩
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(sum.getMemo1());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.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() + "库存明细记录不存在！");
			}
			// (4.5)、验证原料卷号库存明细记录为“在库”状态
			YdmProductDetail  ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.getMaterial_no());
			if (ypdM==null || ypdM.getState()==null || !ypdM.getState().equals("0")) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不是“在库”状态！");
			}
			//    --(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出口卷虚拟物料信息不存在！");
			}
			List<PlnMaterielDetail> v_rec_mtr_out_list=this.getMapper(PlnMaterielDetailMapper.class).doQueryWeb2(plp.getObject_no_vt(),"");
			PlnMaterielDetail v_rec_mtr_out=v_rec_mtr_out_list.get(0);
			
		    //--(4.8)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			String v_coil_no = plp.getMaterial_no().substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			//    --(4.8.1)、获取当前起始流水号
			v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb4(v_coil_no);
			if(v_cnt==null){
				v_cnt=1;
			}else if(v_cnt>99){
				throw new Exception("出口钢卷号超出规则范围，流水号超出最大值99！");
			}
			//--(4.8.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																							
			v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			/*
			    --(4.9)、创建罩退主实绩记录（未列出字段，均插入空值）																																							
			    --(4.9.1)、原料卷计划规格、牌号等信息来源于 pln_materiel_detail 表																																							
			    --(4.9.2)、原料卷实际规格、牌号等信息来源于 ydm_product_detail 表																																							
			    --(4.9.3)、出口卷计划规格、牌号等信息来源于 pln_materiel_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);
			MesCrAnnealM mcam=new MesCrAnnealM();
			mcam.setSchedule_no(plp.getAn_plan_no());
			mcam.setMaterial_no(plp.getMaterial_no());
			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_src(ypdM.getMaterailcoilno());
			mcam.setMtr_thk(ypdM.getThick());
			mcam.setMtr_wdt(ypdM.getWidth());
			mcam.setMtr_len(ypdM.getLength());
			mcam.setMtr_inn_dia(ypdM.getDiameter_inn());
			mcam.setMtr_out_dia(ypdM.getDiameter_out());
			mcam.setMtr_thr_wgt(ypdM.getTheoryweight());
			mcam.setMtr_act_wgt(ypdM.getFactweight());
			mcam.setSteel_code(ypdM.getSteelcode());
			mcam.setMachine_code(sum.getMemo1());
			mcam.setStatus("01");
			mcam.setCharge_date(wrk_date);
			mcam.setCharge_ord(wrk_ord);
			mcam.setCharge_grp(wrk_grp);
			mcam.setCharge_time(new Date());
			mcam.setCoil_no(v_coil_no);
			mcam.setAim_thk(v_rec_mtr_out.getThick());
			mcam.setAim_wdt(v_rec_mtr_out.getWidth());
			mcam.setAim_len(v_rec_mtr_out.getLength());
			mcam.setAim_inn_dia(v_rec_mtr_out.getDiameter_inn());
			mcam.setAim_out_dia(v_rec_mtr_out.getDiameter_out());
			mcam.setAct_thk(ypdM.getThick());
			mcam.setAct_wdt(ypdM.getWidth());
			mcam.setAct_len(ypdM.getLength());
			mcam.setAct_inn_dia(ypdM.getDiameter_inn());
			mcam.setAct_out_dia(ypdM.getDiameter_out());
			mcam.setCoil_thr_wgt(ypdM.getTheoryweight());//?
			mcam.setCoil_act_wgt(ypdM.getFactweight());//?
			mcam.setProd_order_no(v_rec_mtr_out.getProd_order_no());
			mcam.setOrder_no(v_rec_mtr_out.getOrder_no());
			mcam.setHand_over_status("0");
			mcam.setCreate_opr(username);
			mcam.setCreate_time(new Date());
			mcam.setPk_ask_code(v_rec_mtr_out.getPk_ask_code());
			mcam.setPk_ask_desc(v_rec_mtr_out.getPk_ask_desc());
			this.getMapper(MesCrAnnealMMapper.class).insert(mcam);
			//  --(4.10)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）； ？？
			MesCrAnnealM  mcsm=new MesCrAnnealM();
			mcsm.setMachine_code(sum.getMemo1());//机台号
			mcsm.setSchedule_no(plp.getAn_plan_no());//作业计划号
			mcsm.setMaterial_no(plp.getMaterial_no());//投料卷号
			mcsm.setMaterial_no_vt(plp.getObject_no_vt());//虚拟卷号 
			List<MesCrAnnealM> lmcsm=new ArrayList<MesCrAnnealM>();
			
			//时间
			SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");//设置日期格式
		    String date = dfs.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
		    mcsm.setMemo(date);
		    lmcsm.add(mcsm);
		    this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMAdd(lmcsm); 
			
			//调用物流模块（仓库管理）接口，对原料卷进行生产投料出库操作（接口由物流模块提供）；																																							
			YdmProductDetail ypd=new YdmProductDetail();
			ypd.setCoilno(mcam.getMaterial_no());			
			ypd.setMemo(date);// 传入操作时间字符串带毫秒
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			cp.setObject(ypd);
			this.getBean(LmsApiServiceImpl.class).doOutStorage(cp);
					
			try{
				this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(mcam.getMaterial_no(),true);
			}catch(Exception e){
				e.printStackTrace();
			}
			
			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
//			if ("1".equals(isOpen)) {
//			
//				// 记录成本异动点：20230811刘侣
//				ComBaseCbYdd cd = new ComBaseCbYdd();
//				
//				cd.setInstDisp("01");
//				
//				// 当前产线：
//				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.setInvQtyUnit("块");
//				cd.setInvWidth(ypdM.getWidth() != null ? String.valueOf(ypdM.getWidth()) : "0");
//				cd.setCreateId(userId);
//				
//				cd.setInvLength(ypdM.getLength() != null ? String.valueOf(ypdM.getLength()) : "0");
//				
//				cd.setProdName(ypdM.getProd_name());
//				cd.setInvThick(ypdM.getThick() != null ? String.valueOf(ypdM.getThick()) : "0");
//				
//				// 退火上料这里ypdM查的就是投料卷：
//				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(prevcoil); // 投料卷号
//				cd.setSysId("IA");
//				cd.setOrderItem(ypdM.getOrderno());
//				
//				cd.setBeTransUnit("t");
//				
//				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.setInvId(ypdM.getCoilno());
//				cd.setInvQty("1");
//				cd.setSrcFac("1");
//				cd.setGrade("40740801".equals(ypdM.getJudgeresult()) ? "1" : "5"); // 正品　1　协议　3　次品　5
//				cd.setProdClassNo("H");
//				
//				// 存入表：1、上料一抛：原料转库（47）（原料上料准备生产时抛送）
//				cd.setActivityId("55A");
//				cd.setExecJobFunc("N");
//				cd.setDataTypeIdx("O");
//				cd.setProdTypeNo("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 + "转库");
//				
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
//				// 对已有数据进行修改：
//				cd.setDataTypeIdx("N");
//				cd.setProdTypeNo("CTR");
//				cd.setManageip("YTTH");
//				cd.setLocNo("YTTH");
//				cd.setAppId("退火接收原料"); // 优特酸洗入库
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 三抛：酸洗上料（41，开始生产
//				cd.setActivityId("41A");
//				cd.setDataTypeIdx("O");
//				cd.setAppId("退火上料"); // 优特酸洗消耗
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// end
//			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "上料", username, opr_time, mcam.getMaterial_no(), null, null, null, (("M0004".equals(mcam.getMachine_code()))?"宝信退火炉":"艾伯纳退火炉"));
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}		
		r.setState("200");
		r.setMsgInfo("上料成功!");
		return r;
	}
	
	/***
	 * 动作处理-上料按钮     
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * machine_code机台号
	 * memo2：登录班组，
	 * memo3:登录用户名
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doAnnealInsWeb_DG(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;		
		// 优特钢目前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;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要上料的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				r.setState("500");
				r.setMsgInfo("参数错误：机台代码不能为空！");
				return r;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}						
		}
		//(2)、验证机台基础信息存在
		ComBaseMachine machine = new ComBaseMachine();
		machine.setMachine_code(sum.getObjectList().get(0).getMachine_code());
		v_cnt = this.getMapper(ComBaseMachineMapper.class).count(machine);
		if (v_cnt <= 0) {
			r.setMsgInfo("机台代码：" + sum.getObjectList().get(0).getMachine_code() + "，\n机台基础信息不存在！");
			r.setState("500");
			return r;
		}
		//（2.1)、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
		ComBaseMachine machine2 = new ComBaseMachine();
		machine2.setMachine_code(sum.getObjectList().get(0).getMachine_code());
		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.getObjectList().get(0).getMachine_code() + "\n设备编号未配置，无法处理！");
			r.setState("500");
			return r;
		}
		//（3）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		String dbTime=rmDb.getData().toString().substring(11);
		String wrk_date=null,wrk_ord=null,wrk_grp=null;
		if("200".equals(rmDb.getState())){
			dbTime=rmDb.getData().toString().substring(11);
			wrk_date=rmDb.getData().toString().substring(0,10);		
			if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
				wrk_ord="1";
			}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
				wrk_ord="2";
			}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
				wrk_ord="1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date;
				try {
					date = formatYmd.parse(wrk_date);
				} catch (Exception e) {
					throw new Exception("获取数据库时间失败，请稍后重试");
				}
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
				wrk_date=formatYmd.format(c.getTime());
			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}
		//（3.4）、根据计算的日期班次，获取交接班记录的班组
		MesShiftM msm=new MesShiftM();
		msm.setMachine_code("M0005");
		msm.setWrk_date(wrk_date);
		msm.setWrk_ord(wrk_ord);
		v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
		if(v_cnt<=0){
			wrk_grp=sum.getMemo2();//   --暂无交接班记录，则使用前端传入的班组代码
		}else{
			// 否则获取交接班记录中的班组
			List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
			wrk_grp=lmsm.get(0).getWrk_grp();
		}
		// (4)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			//  (4.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(plp.getMachine_code());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			// (4.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(plp.getMachine_code());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
						+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
			}
			PlnAnnealPlanDetail cuttdel = new PlnAnnealPlanDetail();
			cuttdel.setMachine_code(plp.getMachine_code());
			cuttdel.setAn_plan_no(plp.getAn_plan_no());
			cuttdel.setObject_no_vt(plp.getObject_no_vt());
			cuttdel.setObject_no(plp.getMaterial_no());
			List<PlnAnnealPlanDetail> v_rec_pln_d = this.getMapper(PlnAnnealPlanDetailMapper.class).findWithCondition(cuttdel, null, null, 0, 0);
			//2018-11-29 只有是已下发状态的钢卷才能下发
			if(v_rec_pln_d!=null && v_rec_pln_d.size()>0){
				if(!"5BAN02".equals(v_rec_pln_d.get(0).getStatus())){
					throw new Exception("当前状态{"+v_rec_pln_d.get(0).getStatus()+"}不为已下发");
				}
			}
			//--(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)、验证指定的计划，还未创建罩退作业主实绩
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(plp.getMachine_code());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.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() + "库存明细记录不存在！");
			}
			// (4.5)、验证原料卷号库存明细记录为“在库”状态
			YdmProductDetail tYdm3 = new YdmProductDetail();
			tYdm3.setCoilno(plp.getMaterial_no());
			YdmProductDetail  ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.getMaterial_no());
			if (ypdM==null || ypdM.getState()==null || !ypdM.getState().equals("0")) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不是“在库”状态！");
			}
			// (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出口卷虚拟物料信息不存在！");
			}
			List<PlnMaterielDetail> v_rec_mtr_out_list=this.getMapper(PlnMaterielDetailMapper.class).doQueryWeb2(plp.getObject_no_vt(),"");
			PlnMaterielDetail v_rec_mtr_out=v_rec_mtr_out_list.get(0);
			
		    //--(4.8)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			String v_coil_no = plp.getMaterial_no().substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			//(4.8.1)、获取当前起始流水号
			v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb4(v_coil_no);
			if(v_cnt==null){
				v_cnt=1;
			}else if(v_cnt>99){
				throw new Exception("出口钢卷号超出规则范围，流水号超出最大值99！");
			}
			//--(4.8.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																							
			v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			/*
			    --(4.9)、创建罩退主实绩记录（未列出字段，均插入空值）																																							
			    --(4.9.1)、原料卷计划规格、牌号等信息来源于 pln_materiel_detail 表																																							
			    --(4.9.2)、原料卷实际规格、牌号等信息来源于 ydm_product_detail 表																																							
			    --(4.9.3)、出口卷计划规格、牌号等信息来源于 pln_materiel_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);
			MesCrAnnealM mcam=new MesCrAnnealM();
			mcam.setSchedule_no(plp.getAn_plan_no());
			mcam.setMaterial_no(plp.getMaterial_no());
			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_src(ypdM.getMaterailcoilno());
			mcam.setMtr_thk(ypdM.getThick());
			mcam.setMtr_wdt(ypdM.getWidth());
			mcam.setMtr_len(ypdM.getLength());
			mcam.setMtr_inn_dia(ypdM.getDiameter_inn());
			mcam.setMtr_out_dia(ypdM.getDiameter_out());
			mcam.setMtr_thr_wgt(ypdM.getTheoryweight());
			mcam.setMtr_act_wgt(ypdM.getFactweight());
			mcam.setSteel_code(ypdM.getSteelcode());
			mcam.setMachine_code(plp.getMachine_code());
			mcam.setStatus("01");
			mcam.setCharge_date(wrk_date);
			mcam.setCharge_ord(wrk_ord);
			mcam.setCharge_grp(wrk_grp);
			mcam.setCharge_time(new Date());
			mcam.setCoil_no(v_coil_no);
			mcam.setAim_thk(v_rec_mtr_out.getThick());
			mcam.setAim_wdt(v_rec_mtr_out.getWidth());
			mcam.setAim_len(v_rec_mtr_out.getLength());
			mcam.setAim_inn_dia(v_rec_mtr_out.getDiameter_inn());
			mcam.setAim_out_dia(v_rec_mtr_out.getDiameter_out());
			mcam.setAct_thk(ypdM.getThick());
			mcam.setAct_wdt(ypdM.getWidth());
			mcam.setAct_len(ypdM.getLength());
			mcam.setAct_inn_dia(ypdM.getDiameter_inn());
			mcam.setAct_out_dia(ypdM.getDiameter_out());
			mcam.setCoil_thr_wgt(ypdM.getTheoryweight());//?
			mcam.setCoil_act_wgt(ypdM.getFactweight());//?
			mcam.setProd_order_no(v_rec_mtr_out.getProd_order_no());
			mcam.setOrder_no(v_rec_mtr_out.getOrder_no());
			mcam.setHand_over_status("0");
			mcam.setCreate_opr(username);
			mcam.setCreate_time(new Date());
			mcam.setPk_ask_code(v_rec_mtr_out.getPk_ask_code());
			mcam.setPk_ask_desc(v_rec_mtr_out.getPk_ask_desc());
			this.getMapper(MesCrAnnealMMapper.class).insert(mcam);
			//  --(4.10)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）； ？？
			MesCrAnnealM  mcsm=new MesCrAnnealM();
			mcsm.setMachine_code(plp.getMachine_code());//机台号
			mcsm.setSchedule_no(plp.getAn_plan_no());//作业计划号
			mcsm.setMaterial_no(plp.getMaterial_no());//投料卷号
			mcsm.setMaterial_no_vt(plp.getObject_no_vt());//虚拟卷号 
			List<MesCrAnnealM> lmcsm=new ArrayList<MesCrAnnealM>();		
			//时间
			SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");//设置日期格式
		    String date = dfs.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
		    mcsm.setMemo(date);
		    lmcsm.add(mcsm);
		    this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMAdd(lmcsm); 
			
			//调用物流模块（仓库管理）接口，对原料卷进行生产投料出库操作（接口由物流模块提供）；																																							
			YdmProductDetail ypdu=new YdmProductDetail();
			ypdu.setCoilno(mcam.getMaterial_no());
			// 传入操作时间字符串带毫秒
			ypdu.setMemo(date);
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			cp.setObject(ypdu);
			this.getBean(LmsApiServiceImpl.class).doOutStorage(cp);
			
			try{
				this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(mcam.getMaterial_no(),true);
			}catch(Exception e){
				e.printStackTrace();
			}
			
//			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
//			if ("1".equals(isOpen)) {
//			
//				// 记录成本异动点：20230811刘侣
//				ComBaseCbYdd cd = new ComBaseCbYdd();
//				cd.setCoilStus("0"); // 综判前算半成品0，综判入库后算成品1
//				cd.setInstDisp("01");
//				cd.setDataTypeIdx("N");
//				// 当前产线：
//				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(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(ypdM.getCoilno());
//				cd.setInvQty("1");
//				cd.setSrcFac("1");
//				cd.setGrade("40740801".equals(ypdM.getJudgeresult()) ? "1" : "5"); // 正品　1　协议　3　次品　5
//				cd.setProdClassNo("H");
//
//				// 存入表：1、上料一抛：原料转库（47）（原料上料准备生产时抛送）
//				cd.setActivityId("55A");
//				cd.setExecJobFunc("N");
//				cd.setDataTypeIdx("O");
//				cd.setProdTypeNo("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 + "转库");
//				
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
//				// 对已有数据进行修改：
//				cd.setDataTypeIdx("N");
//				cd.setProdTypeNo("CTR");
//				cd.setManageip("YTTH");
//				cd.setLocNo("YTTH");
//				cd.setAppId("退火接收原料"); // 优特酸洗入库
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 三抛：酸洗上料（41，开始生产
//				cd.setActivityId("41A");
//				cd.setDataTypeIdx("O");
//				cd.setAppId("退火上料");
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// end
//			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "上料", username, opr_time, mcam.getMaterial_no(), null, null, null, "南方退火炉");
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}		
		r.setState("200");
		r.setMsgInfo("上料成功!");
		return r;
	}
				
	/**
	 * 动作处理 -恢复计划 
	 *  objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1：机台代码，
	 * memo2:登录用户名
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doUpdateWeb(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;	
		//  --(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要恢复计划的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}		
		// --(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			//(2.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(sum.getMemo1());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(2.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(sum.getMemo1());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_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.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(2.5)、验证罩退作业主实绩存在，且为“未交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(sum.getMemo1());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()!=null && !v_rec_cam.getHand_over_status().equals("0")){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能恢复计划！\n可取消交工，再进行此操作！");
		    }
		    //(2.6)、调用生产管理接口，验证是否能执行相关操作，如果不满足条件，返回错误信息到前端，结束操作（接口由生产管理模块提供）；	 ??																																						
		    this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMCancelValid(lmcam);
		    //(2.7)、调用物流模块接口，验证原料卷可撤销生产出库操作，如果不满足条件，返回错误信息到前端，结束操作（接口由物流模块提供）；		
			YdmProductDetail ypdu=new YdmProductDetail();
			ypdu.setCoilno(plp.getMaterial_no());
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();	
			cp.setObject(ypdu);
			r = this.getBean(LmsApiServiceImpl.class).doDepend(cp);
			if("500".equals(r.getState())){
				throw new Exception(r.getMsgInfo());
			}
			//--(2.8)、删除罩退作业实绩
			this.getMapper(MesCrAnnealMMapper.class).doDelete(sum.getMemo1(),plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());			
			// --(2.9)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）；？？																																							
			this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMCancel(lmcam);
			//  --(2.10)、调用物流模块接口，执行原料卷出库撤销相关操作（接口由物流模块提供）；																																							
			this.getBean(LmsApiServiceImpl.class).doCancelOut(cp);
			
			try{
				this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(plp.getMaterial_no(),false);
			}catch(Exception e){
				e.printStackTrace();
			}
			
//			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
//			if ("1".equals(isOpen)) {
//			
//				// 记录成本异动点：20230811刘侣
//				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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(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(ypdM.getCoilno());
//				cd.setInvQty("1");
//				cd.setSrcFac("1");
//				cd.setGrade("40740801".equals(ypdM.getJudgeresult()) ? "1" : "5"); // 正品　1　协议　3　次品　5
//				cd.setProdClassNo("H");
//
//				// 存入表：1、上料一抛：原料转库（47）（原料上料准备生产时抛送）
//				cd.setActivityId("55A");
//				cd.setExecJobFunc("N");
//				cd.setDataTypeIdx("N");
//				cd.setProdTypeNo("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 + "取消转库");
//				
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
//				// 对已有数据进行修改：
//				cd.setDataTypeIdx("O");
//				cd.setProdTypeNo("CTR");
//				cd.setManageip("YTTH");
//				cd.setLocNo("YTTH");
//				cd.setAppId("退火取消接收原料");
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 三抛：酸洗上料（41，开始生产
//				cd.setActivityId("41A");
//				cd.setDataTypeIdx("N");
//				cd.setAppId("退火取消上料");
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// end
//			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "恢复计划", username, opr_time, plp.getMaterial_no(), null, null, null, (("M0004".equals(plp.getMachine_code()))?"宝信退火炉":"艾伯纳退火炉"));
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		r.setState("200");
		r.setMsgInfo("恢复计划成功");
		return r;
	}
	
	
	/**
	 * 动作处理 -恢复计划 
	 *  objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * machine_code:机台代码
	 * memo2:登录用户名
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doUpdateWeb_DG(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;		
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要恢复计划的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				r.setState("500");
				r.setMsgInfo("参数错误：机台代码不能为空！");
				return r;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}
		
		// (2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			// (2.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(plp.getMachine_code());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			// (2.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(plp.getMachine_code());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_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.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(2.5)、验证罩退作业主实绩存在，且为“未交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(plp.getMachine_code());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()!=null && !v_rec_cam.getHand_over_status().equals("0")){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能恢复计划！\n可取消交工，再进行此操作！");
		    }
		    //--(2.6)、调用生产管理接口，验证是否能执行相关操作，如果不满足条件，返回错误信息到前端，结束操作（接口由生产管理模块提供）；	 ??																																						
		    this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMCancelValid(lmcam);
		    //--(2.7)、调用物流模块接口，验证原料卷可撤销生产出库操作，如果不满足条件，返回错误信息到前端，结束操作（接口由物流模块提供）；		
			YdmProductDetail ypdu=new YdmProductDetail();
			ypdu.setCoilno(plp.getMaterial_no());
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			cp.setObject(ypdu);
			r = this.getBean(LmsApiServiceImpl.class).doDepend(cp);
			if("500".equals(r.getState())){
				throw new Exception(r.getMsgInfo());
			}
			//--(2.8)、删除罩退作业实绩
			this.getMapper(MesCrAnnealMMapper.class).doDelete(plp.getMachine_code(),plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());
			
			//--(2.9)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）；？？																																							
			this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMCancel(lmcam);
			//--(2.10)、调用物流模块接口，执行原料卷出库撤销相关操作（接口由物流模块提供）；																																							
			this.getBean(LmsApiServiceImpl.class).doCancelOut(cp);
			try{
				this.getBean(PlnProdorderStatisticServiceImpl.class).updateProdSta(plp.getMaterial_no(),false);
			}catch(Exception e){
				e.printStackTrace();
			}
			
//			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
//			if ("1".equals(isOpen)) {
//			
//				// 记录成本异动点：20230811刘侣
//				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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(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(ypdM.getCoilno());
//				cd.setInvQty("1");
//				cd.setSrcFac("1");
//				cd.setGrade("40740801".equals(ypdM.getJudgeresult()) ? "1" : "5"); // 正品　1　协议　3　次品　5
//				cd.setProdClassNo("H");
//				
//				// 存入表：1、上料一抛：原料转库（47）（原料上料准备生产时抛送）
//				cd.setActivityId("55A");
//				cd.setExecJobFunc("N");
//				cd.setDataTypeIdx("N");
//				cd.setProdTypeNo("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 + "取消转库");
//				
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
//				// 对已有数据进行修改：
//				cd.setDataTypeIdx("O");
//				cd.setProdTypeNo("CTR");
//				cd.setManageip("YTTH");
//				cd.setLocNo("YTTH");
//				cd.setAppId("退火取消接收原料");
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// 三抛：酸洗上料（41，开始生产
//				cd.setActivityId("41A");
//				cd.setDataTypeIdx("N");
//				cd.setAppId("退火取消上料");
//				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId());
//				// end
//			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "恢复计划", username, opr_time, plp.getMaterial_no(), null, null, null, "南方退火炉");
			this.getMapper(MesOprLogMapper.class).insert(mol);
		}
		r.setState("200");
		r.setMsgInfo("恢复计划成功");
		return r;
	}
		
	/**
	 * 保存  *  updateM
	 * object中：
	 * schedule_no作业计划号
	 * material_no_vt虚拟卷号
	 * material_no原料卷号
	 * memo1：机台代码，
	 * memo2:登录用户名
	 * */
	public ResultModel  doSaveWeb(CommonPage<MesCrAnnealM> sum) {
		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);
		MesCrAnnealM mcm = sum.getObject();
		
		Integer v_cnt;
		if(mcm==null){
			r.setState("500");
			r.setMsgInfo("请传入参数！");
			return r;
		}
		if(mcm.getHeating_time()!=null && mcm.getHeating_time()>9999){
			r.setState("500");
			r.setMsgInfo("实际升温时长（单位为分钟）范围【0-9999】");
			return r;
		}
		if(mcm.getKeeping_time()!=null && mcm.getKeeping_time()>9999){
			r.setState("500");
			r.setMsgInfo("实际保温时长（单位为分钟）范围【0-9999】");
			return r;
		}
		if(mcm.getHoodoff_temp()!=null && mcm.getHoodoff_temp()>9999){
			r.setState("500");
			r.setMsgInfo("去加热罩温度应小于10000");
			return r;
		}
		if(mcm.getAnneal_temp_min()!=null && mcm.getAnneal_temp_min()>9999){
			r.setState("500");
			r.setMsgInfo("退火温度最小值应小于10000");
			return r;
		}
		if(mcm.getAnneal_temp_max()!=null && mcm.getAnneal_temp_max()>9999){
			r.setState("500");
			r.setMsgInfo("退火温度最大值应小于10000");
			return r;
		}
		if(mcm.getAnneal_temp_avg()!=null && mcm.getAnneal_temp_avg()>9999){
			r.setState("500");
			r.setMsgInfo("退火温度平均值应小于10000");
			return r;
		}
		if(mcm.getCooling_time_hood()!=null && mcm.getCooling_time_hood()>9999){
			r.setState("500");
			r.setMsgInfo("带罩冷却时长（min）应小于10000");
			return r;
		}
		if(mcm.getCooling_time()!=null && mcm.getCooling_time()>9999){
			r.setState("500");
			r.setMsgInfo("实际冷却时间应小于10000");
			return r;
		}
		if(mcm.getOut_temp_set()!=null && mcm.getOut_temp_set()>9999){
			r.setState("500");
			r.setMsgInfo("出炉设定温度应小于10000");
			return r;
		}
		if(mcm.getIn_fur_seq()!=null && mcm.getIn_fur_seq()>99){
			r.setState("500");
			r.setMsgInfo("炉内位置应小于100");
			return r;
		}				
		//  --(1)、验证罩退作业计划主记录存在
		PlnAnnealPlan pcp=new PlnAnnealPlan();
		pcp.setMachine_code(sum.getMemo1());
		pcp.setAn_plan_no(mcm.getSchedule_no());
		int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
		if (count<=0) {
			r.setMsgInfo("机台代码："+sum.getMemo1()+"\n作业计划号："+mcm.getSchedule_no()+"\n作业计划主记录不存在！");
			r.setState("500");
			return r;
		}
		//  --(2)、验证罩退作业计划明细记录存在
		PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
		pcpd.setMachine_code(sum.getMemo1());
		pcpd.setAn_plan_no(mcm.getSchedule_no());
		pcpd.setObject_no_vt(mcm.getMaterial_no_vt());
		pcpd.setObject_no(mcm.getMaterial_no());
		int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
		if (count2<=0) {
			r.setState("500");
			r.setMsgInfo("机台代码："+sum.getMemo1()+"\n作业计划号："+mcm.getSchedule_no()+"\n虚拟卷号："+mcm.getMaterial_no_vt()+""
					+ "\n原料卷号："+mcm.getMaterial_no()+"\n作业计划明细记录不存在！");
			return r;
		}
		//  --(3)、验证原料卷对应的罩退主实绩存在，且为“未交工”状态
		MesCrAnnealM mCross = new MesCrAnnealM();
		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(MesCrAnnealMMapper.class).count(mCross);
		if (v_cnt<=0) {
			r.setState("500");
			r.setMsgInfo("原料卷号：" +mcm.getMaterial_no()+ "，当前不存在罩退作业实绩！");
			return r;
		}
	    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
	    MesCrAnnealM v_rec_cam =lmcam.get(0);
	    if(v_rec_cam.getHand_over_status()!=null && !v_rec_cam.getHand_over_status().equals("0")){
	    	r.setState("500");
	    	r.setMsgInfo("原料卷号："+mcm.getMaterial_no()+"当前已生产交工，不能修改生产实绩！可取消交工，再进行此操作！");
			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;
		}	    	    
		//(2.11)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
		String v_coil_no=null;
		String v_leo="";
		if(mcm.getFurnace_no()!=null && !"".equals(mcm.getFurnace_no())){
			int leo1x = Integer.parseInt(mcm.getFurnace_no());
			mcm.setFurnace_no(leo1x+"");
			String v_syh=lpad(mcm.getFurnace_no(), 2, "0");
			if(v_rec_cam.getCoil_no()!=null){
				v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
				if(!v_syh.equals(v_leo)){
					v_coil_no = mcm.getMaterial_no().substring(0, 8) + "T"+ lpad(mcm.getFurnace_no(), 2, "0");
				}				
			}else{
				v_coil_no = mcm.getMaterial_no().substring(0, 8) + "T"+ lpad(mcm.getFurnace_no(), 2, "0");
			}			
		}else{
			v_coil_no = mcm.getMaterial_no().substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
		}
		if(v_coil_no!=null){
			//(2.11.1)、获取当前起始流水号
			v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb6(v_coil_no,mcm.getSchedule_no(),mcm.getMaterial_no());
			if(v_cnt==null){
				v_cnt=1;
			}else if(v_cnt>99){
				String v_message="作业计划号{"+mcm.getSchedule_no()+"} 原料卷号{"+mcm.getMaterial_no()+"} 出口钢卷号超出规则范围，流水号超出最大值99！";
				r.setState("500");
		    	r.setMsgInfo(v_message);
				return r;
			}
			//--(2.11.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																						
			v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
		}
		
		if(mcm.getFurnace_no()!=null && !"".equals(mcm.getFurnace_no())){
			String v_syh=lpad(mcm.getFurnace_no(), 2, "0");
			if(v_rec_cam.getCoil_no()!=null){
				v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
				if(!v_syh.equals(v_leo)){
					mcm.setCoil_no(v_coil_no);
				}				
			}else{
				mcm.setCoil_no(v_coil_no);
			}
			
		}
		
	    //--(4)、修改罩退生产实绩主记录（所有字段都可能为空值，注意SQL的处理）
	    mcm.setUpdate_opr(username);
	    mcm.setUpdate_time(new Date());
	    mcm.setMachine_code(sum.getMemo1());
	    this.getMapper(MesCrAnnealMMapper.class).doUpdate(mcm);	    
	    //2019-02-21
  		/*
  		检验批分批规则：
  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
  		 */
	    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
  		if(mcm.getBatch_no()!=null && !"".equals(mcm.getBatch_no())){
  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+mcm.getBatch_no()+"'", null, 0, 0);
  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
  					try{
  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
  					}catch(Exception e){
  						
  					}
  			}
  		}
	    
	    //=======================质量检验委托开始=============================
	    if(mcm.getBatch_no()!=null && !"".equals(mcm.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
	    	try{
				QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
				String prod_order_no=v_rec_cam.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){					
					if(mc_list!=null && mc_list.size()>0){
						for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
							String key = grouplist.getKey();
							List<MesCrAnnealM> listCes = grouplist.getValue();
							for(MesCrAnnealM mcam:listCes){
								String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
								if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcam.getMaterial_no())){
									ajsfp.setInspection_lot(mcam.getInspection_lot());
									MesCrAnnealM mCrossleo = new MesCrAnnealM();
									mCrossleo.setSchedule_no(mcam.getSchedule_no());
									mCrossleo.setMaterial_no(mcam.getMaterial_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
								}
							}
						}
					}
					
					ajsfp.setBatch_no(mcm.getBatch_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.setHeat_no(mcm.getBatch_no());//炉号      
					ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
					ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
					ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
					ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
					ajsfp.setBoard_no(mcm.getMaterial_no());
					
					ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
					ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
					//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
					List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
					int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(mcm.getMaterial_no_vt(), "B");
					// 获取工艺路径包含成分或者材质类
					if(judge_Contain_Qcm!=-1){
						ajsfp.setPline_seq((long)judge_Contain_Qcm);
						if(mcm!=null && mcm.getBatch_no()!=null && v_rec_cam.getBatch_no()!=null){
							if(!v_rec_cam.getBatch_no().equals(mcm.getBatch_no())){
								QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
								qjsprem.setDesign_key(lpp.get(0).getDesign_key());
								qjsprem.setInspection_lot(v_rec_cam.getInspection_lot());
								CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
								sum22.setObject(qjsprem);
								this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
							}
						}
						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.getMsgInfo());
						}
					}
				}
			}catch(Exception e){
				e.printStackTrace();
			}
	    }
		//==========================质量检验委托结束==================================
	    //日志
	    MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "保存", username, opr_time, mcm.getMaterial_no(), null, null, null, lcbm.get(0).getMachine_name());
	    this.getMapper(MesOprLogMapper.class).insert(mol);
	    r.setState("200");
	    r.setMsgInfo("保存成功！");
		return r;
	}
	
	
	/***
	 * 动作处理--交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录班组
	 * memo3:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOff(CommonPage<PlnAnnealPlan> 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 nextP = "";
		
		Integer v_cnt;
		DateFormat dftwo = new SimpleDateFormat("yyyy-MM-dd");
		//--(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			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;
		}		
		// --优特钢目前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;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}	
		//（2）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		String dbTime=rmDb.getData().toString().substring(11);
		String wrk_date=null,wrk_ord=null,wrk_grp=null;
		if("200".equals(rmDb.getState())){
			dbTime=rmDb.getData().toString().substring(11);
			wrk_date=rmDb.getData().toString().substring(0,10);			
			if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
				wrk_ord="1";
			}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
				wrk_ord="2";
			}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
				wrk_ord="1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date;
				try {
					date = formatYmd.parse(wrk_date);
				} catch (Exception e) {
					throw new Exception("获取数据库时间失败，请稍后重试");
				}
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
				wrk_date=formatYmd.format(c.getTime());
			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}
		//（2.4）、根据计算的日期班次，获取交接班记录的班组
		MesShiftM msm=new MesShiftM();
		if(sum.getMemo1().equals("M0009")){
			msm.setMachine_code("M0005");
		}else{
			msm.setMachine_code(sum.getMemo1());
		}
		msm.setWrk_date(wrk_date);
		msm.setWrk_ord(wrk_ord);
		v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
		if(v_cnt<=0){
			wrk_grp=sum.getMemo2();//   --暂无交接班记录，则使用前端传入的班组代码
		}else{
			// 否则获取交接班记录中的班组
			List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
			wrk_grp=lmsm.get(0).getWrk_grp();
		}
		// (3)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			// (3.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(sum.getMemo1());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(3.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(sum.getMemo1());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
						+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
			}			
			//(3.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原料卷虚拟物料信息不存在！");
			}
			//(3.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(3.5)、验证原料卷对应的罩退主实绩存在，且为“未交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(sum.getMemo1());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()!=null && !v_rec_cam.getHand_over_status().equals("0")){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能重复操作！");
		    }
			//    --(3.6)、验证实绩中必要的数据项都填写 
			if(v_rec_cam.getFurnace_no()==null){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"炉座号为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getBatch_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉次号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getIn_fur_seq()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉内序号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_date()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料日期为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_ord()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班次为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_grp()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班组为空，不能交工，请先填写完整并保存！");
		    }
			if(v_rec_cam.getCharge_time()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"生产开始时间为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getCoil_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷号为空，不能交工，数据异常，请联系系统管理员！");
		    }
		    if(v_rec_cam.getCoil_act_wgt()==null || v_rec_cam.getCoil_act_wgt()<0){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷重量为空或小于零，不能交工，请先填写完整并保存！");
		    }
		    //生产结束时间
			if(v_rec_cam.getDischarge_time()==null){
				v_rec_cam.setDischarge_time(new Date());
			}
			 
			//--(2.11)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			//String v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			String v_coil_no=null;
			String v_leo="";
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
					}
				}else{
					v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
				}
				
			}else{
				v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			}
			if(v_coil_no!=null){
				//    --(2.11.1)、获取当前起始流水号
				v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb6(v_coil_no,v_rec_cam.getSchedule_no(),v_rec_cam.getMaterial_no());
				if(v_cnt==null){
					v_cnt=1;
				}else if(v_cnt>99){
					String v_message="作业计划号{"+v_rec_cam.getSchedule_no()+"} 原料卷号{"+v_rec_cam.getMaterial_no()+"} 出口钢卷号超出规则范围，流水号超出最大值99！";
					r.setState("500");
			    	r.setMsgInfo(v_message);
					return r;
				}
				//--(2.11.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																						
				v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			}
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_rec_cam.setCoil_no(v_coil_no);
					}					
				}else{
					v_rec_cam.setCoil_no(v_coil_no);
				}
				
			}
			v_rec_cam.setDischarge_date(dftwo.format(now));//交工日期当产出日期
		    this.getMapper(MesCrAnnealMMapper.class).update(v_rec_cam);
						
		    List<PlnMaterielDetail> lpmdc=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			if (Utils.isEmpty(lpmdc)) {
				throw new Exception("未找到虚拟子卷信息!");
			}			
			// 处理库存信息的虚拟子卷号 2018-11-09
			MesCrAnnealM mcam  = new MesCrAnnealM();
			BeanUtils.copyProperties(v_rec_cam, mcam);
			mcam.setMaterial_no_vt(lpmdc.get(0).getObject_no_vt());
			
		    //--(3.7)、调用物流模块接口，执行出口钢卷入库相关操作（接口由物流模块提供）；																																							
			YdmProductDetail p=new YdmProductDetail();
			p.setCoilno(v_rec_cam.getCoil_no());
			//入库的信息不全......
			CommonPage<MesCrAnnealM> cp2=new CommonPage<MesCrAnnealM>();
			
			cp2.setObject(mcam);
			//调用物流模块（仓库管理）接口，逐一将分条子卷实绩各子卷，插入库存记录（待入库状态）；	
			try{
				//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
				String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
				nextP = nextProcessCode;
				if(nextProcessCode==null || "".equals(nextProcessCode)){
					cp2.setMemo1("500203");//成品库					
					//生产订单统计 统计量并修改生产订单状态
				    try{
//				    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,true);
				    }catch(Exception e){
				    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
				    	e.printStackTrace();
				    }				
				}else{
					cp2.setMemo1("500202");//在制品库
				}
			}catch(Exception e){
				throw new Exception("获取下道工序异常！"+ e.getMessage());
			}
			//2019-02-21修改
			PlnMaterielDetail pmd_21=new PlnMaterielDetail();
			pmd_21.setObject_no_vt(plp.getObject_no_vt());
			List<PlnMaterielDetail> list_pmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmd_21, 0, 0);
			boolean flag_Ct = false;
			if(list_pmd!=null && list_pmd.size()>0){
				flag_Ct=this.getBean(MesApiDesignInfoImpl.class).getContractType(list_pmd.get(0).getProd_order_no());
			}
			if(flag_Ct){
				cp2.setMemo3("507101");//物料属性，优特钢带
			}			
			try{
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doMesIn2(cp2);
				if(!"200".equals(rmValid.getState())){
					throw new Exception("入库出错！"+rmValid.getMsgInfo());
				}
				
				// 写入库存表后去更新生产订单状态：20230909刘侣；
				YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,true);
					// end
				}
				
				// 检验委托：如果是最后一道工序才需要送样，去做检验委托：
				// 待判信息发送：如果是最后一道工序（进成品库），那么就给isfinal ： 1， 否则就是：0；
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					
					// 发送检验委托信息：20230909刘侣：最后一道工序才送样
					
					this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "1");
					
					// 只有以6开头的订单才去发送检验委托：
					if (ypdQ.getOrderno() != null) {
						ResultModel rmwt = this.getBean(SlmFundFirstDetailServiceImpl.class).sendToJYWT(v_rec_cam.getCoil_no(), true);
  						if ("500".equals(rmwt.getState())) {
  							throw new Exception(rmwt.getMsgInfo());
  						}
					}
					
					// end
				} else {
					// 非最后一道：
					if (v_rec_cam.getCoil_no() != null && ("B".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1))
							 || "H".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1)))) {
						
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), true, "0");
					} else {
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "0");
					}
				}
				// end
				
				
			}catch(Exception ex){
				ex.printStackTrace();
				throw new Exception("物流入库接口出错！"+ ex.getMessage());
			}
						
			try{
				ResultModel rm = this.getBean(QmsApiServiceImpl.class).doQueryJudegeResult(v_rec_cam.getCoil_no());
				if(rm!=null && rm.getData()!=null && (rm.getData() instanceof JudgeResult)){
					JudgeResult jr=(JudgeResult)rm.getData();
					YdmProductDetail ypd=new YdmProductDetail();
					ypd.setCoilno(v_rec_cam.getCoil_no());
					boolean falgggg=false;
					if(jr.getMarginal_result()!=null){
						ypd.setMarginal_result(jr.getMarginal_result());
						falgggg=true;
					}
					if(jr.getMarginal_result_id()!=null){
						ypd.setMarginal_result_id(jr.getMarginal_result_id());
						falgggg=true;
					}
					if(jr.getMeasure_result()!=null){
						ypd.setMeasure_result(jr.getMeasure_result());
						falgggg=true;
					}
					if(jr.getMeasure_result_id()!=null){
						ypd.setMeasure_result_id(jr.getMeasure_result_id());
						falgggg=true;
					}
					if(jr.getSfd_is_lock()!=null){
						ypd.setSfd_is_lock(jr.getSfd_is_lock());
						falgggg=true;
					}
					if(jr.getSfe_is_lock()!=null){
						ypd.setSfe_is_lock(jr.getSfe_is_lock());
						falgggg=true;
					}
					if(jr.getSfu_is_lock()!=null){
						ypd.setSfu_is_lock(jr.getSfu_is_lock());
						falgggg=true;
					}
					if(jr.getSic_is_lock()!=null){
						ypd.setSic_is_lock(jr.getSic_is_lock());
						falgggg=true;
					}
					if(jr.getSizeResult()!=null){
						ypd.setSizeresult(jr.getSizeResult());
						falgggg=true;
					}
					if(jr.getUd_surface_result()!=null){
						ypd.setUd_surface_result(jr.getUd_surface_result());
						falgggg=true;
					}
					if(jr.getUd_surface_result_id()!=null){
						ypd.setUd_surface_result_id(jr.getUd_surface_result_id());
						falgggg=true;
					}
					if(jr.getUp_surface_result()!=null){
						ypd.setUp_surface_result(jr.getUp_surface_result());
						falgggg=true;
					}
					if(jr.getUp_surface_result_id()!=null){
						ypd.setUp_surface_result_id(jr.getUp_surface_result_id());
						falgggg=true;
					}
					if(jr.getUp_surface_flaw() != null) {
						ypd.setUp_surface_flaw(jr.getUp_surface_flaw());
						falgggg= true;
					}
					if(jr.getUd_surface_flaw() != null) {
						ypd.setUd_surface_flaw(jr.getUd_surface_flaw());
						falgggg= true;
					}
					if(jr.getMarginal_flaw()!= null) {
						ypd.setMarginal_flaw(jr.getMarginal_flaw());
						falgggg= true;
					}
					if(falgggg){
//						this.getMapper(YdmProductDetailMapper.class).update(ypd);
					}
				}
			}catch(Exception e){
				System.out.println("调用质量接口报错");
				e.printStackTrace();
			}
						
		    //--(3.8)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；
			try{
				PlnMaterielDetail pmdq=new PlnMaterielDetail();
				pmdq.setObject_no(v_rec_cam.getMaterial_no());
				pmdq.setObject_no_vt(lpmdc.get(0).getObject_no_vt());
				pmdq.setMaterial_no(v_rec_cam.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmdq.setSub_object_no(v_rec_cam.getCoil_no()); // 子卷号
				// 传入操作时间 2018-06-19
				pmdq.setCreate_time(now);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Relation(pmdq);
				
				// 虚拟母卷
				List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Sum(lpmdq.get(0));
			}catch(Exception e){
				e.printStackTrace();
				throw new Exception("计划接口出错！"+ e.getMessage());
			}
					
		    //--(3.9)、修改罩退作业主实绩交工状态																																							
			this.getMapper(MesCrAnnealMMapper.class).doUpdate2(wrk_date,wrk_ord,wrk_grp,username,sum.getMemo1(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());
		
			//2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
	  					try{
	  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
	  					}catch(Exception e){
	  						
	  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){
						
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}
						
						ajsfp.setBatch_no(v_rec_cam.getBatch_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.setHeat_no(v_rec_cam.getBatch_no());//炉号      
						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
						
						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
						List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
						// 获取工艺路径包含成分或者材质类
						if(judge_Contain_Qcm!=-1){
							ajsfp.setPline_seq((long)judge_Contain_Qcm);
							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.getMsgInfo());
							}
						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
		    }
		    
		    
		    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
			    // 记录成本异动点：20230811刘侣
	 			YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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") ? "分条" : "原料";
				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());
//				}
				// end
				
				// 二抛：酸洗接收原料（17）(此时原料还未上酸洗产线) 
				// 对已有数据进行修改：
				cd.setDataTypeIdx("N");
//				cd.setProdTypeNo("CTR");
				cd.setManageip("YTTH");
				cd.setLocNo("YTTH");
				cd.setAppId("退火接收原料");
				
				// 20231130刘侣
//				if (isYcJs <= 0) {
					this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
//				} else {
//					cd.setActivityId("12AB");
//					cd.setAppId("来料加工");
//					this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
//				}
				// end
				
				// 三抛：酸洗上料（41，开始生产
				cd.setActivityId("41A");
				cd.setDataTypeIdx("O");
				cd.setAppId("退火上料");
				cd.setLastMill("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
		    
		    
			//==========================质量检验委托结束==================================
		 	//日志
		    MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "交工", username, opr_time, plp.getMaterial_no(), null, null, null, lcbm.get(0).getMachine_name() + "；下道工序为：" + nextP);
		    this.getMapper(MesOprLogMapper.class).insert(mol);		    
		}	
		r.setState("200");
		r.setMsgInfo("交工成功!");
		return r;
	}
	
	
	/***
	 * 动作处理--交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * machine_code:机台代码
	 * memo2:登录班组
	 * memo3:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOff_DG(CommonPage<PlnAnnealPlan> 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 nextP = "";
		
		Integer v_cnt;
		DateFormat dftwo = new SimpleDateFormat("yyyy-MM-dd");
		// --优特钢目前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;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				r.setState("500");
				r.setMsgInfo("参数错误：机台代码不能为空！");
				return r;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}		
		//  --（2）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		String dbTime=rmDb.getData().toString().substring(11);
		String wrk_date=null,wrk_ord=null,wrk_grp=null;
		if("200".equals(rmDb.getState())){
			dbTime=rmDb.getData().toString().substring(11);
			wrk_date=rmDb.getData().toString().substring(0,10);			
			if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
				wrk_ord="1";
			}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
				wrk_ord="2";
			}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
				wrk_ord="1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date;
				try {
					date = formatYmd.parse(wrk_date);
				} catch (Exception e) {
					throw new Exception("获取数据库时间失败，请稍后重试");
				}
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
				wrk_date=formatYmd.format(c.getTime());
			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}
		//  --（2.4）、根据计算的日期班次，获取交接班记录的班组
		MesShiftM msm=new MesShiftM();
		msm.setMachine_code("M0005");
		msm.setWrk_date(wrk_date);
		msm.setWrk_ord(wrk_ord);
		v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
		if(v_cnt<=0){
			wrk_grp=sum.getMemo2();//   --暂无交接班记录，则使用前端传入的班组代码
		}else{
			//    --否则获取交接班记录中的班组
			List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
			wrk_grp=lmsm.get(0).getWrk_grp();
		}
		
		// (3)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){			
			//  --（2.1)、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
			ComBaseMachine machine2 = new ComBaseMachine();
			machine2.setMachine_code(plp.getMachine_code());
			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;
			}			
			//(3.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(plp.getMachine_code());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(3.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(plp.getMachine_code());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
						+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
			}		
			//--(3.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原料卷虚拟物料信息不存在！");
			}
			//--(3.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//--(3.5)、验证原料卷对应的罩退主实绩存在，且为“未交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(plp.getMachine_code());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()!=null && !v_rec_cam.getHand_over_status().equals("0")){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能重复操作！");
		    }
			//    --(3.6)、验证实绩中必要的数据项都填写 
			if(v_rec_cam.getFurnace_no()==null){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"炉座号为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getBatch_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉次号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getIn_fur_seq()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉内序号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_date()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料日期为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_ord()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班次为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_grp()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班组为空，不能交工，请先填写完整并保存！");
		    }
			if(v_rec_cam.getCharge_time()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"生产开始时间为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getCoil_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷号为空，不能交工，数据异常，请联系系统管理员！");
		    }
		    if(v_rec_cam.getCoil_act_wgt()==null || v_rec_cam.getCoil_act_wgt()<0){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷重量为空或小于零，不能交工，请先填写完整并保存！");
		    }
		    //生产结束时间
			if(v_rec_cam.getDischarge_time()==null){
				v_rec_cam.setDischarge_time(new Date());
			}
			
			//(2.11)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			String v_coil_no=null;
			String v_leo="";
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
					}
				}else{
					v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
				}				
			}else{
				v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			}
			
			if(v_coil_no!=null){
				//--(2.11.1)、获取当前起始流水号
				v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb6(v_coil_no,v_rec_cam.getSchedule_no(),v_rec_cam.getMaterial_no());
				if(v_cnt==null){
					v_cnt=1;
				}else if(v_cnt>99){
					String v_message="作业计划号{"+v_rec_cam.getSchedule_no()+"} 原料卷号{"+v_rec_cam.getMaterial_no()+"} 出口钢卷号超出规则范围，流水号超出最大值99！";
					r.setState("500");
			    	r.setMsgInfo(v_message);
					return r;
				}
				//--(2.11.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																						
				v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			}
			
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_rec_cam.setCoil_no(v_coil_no);
					}					
				}else{
					v_rec_cam.setCoil_no(v_coil_no);
				}
				
			}
			v_rec_cam.setDischarge_date(dftwo.format(now));//20210628交工当前时间当做产出时间
		    this.getMapper(MesCrAnnealMMapper.class).update(v_rec_cam);		
		    
		    List<PlnMaterielDetail> lpmdc=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			if (Utils.isEmpty(lpmdc)) {
				throw new Exception("未找到虚拟子卷信息!");
			}
			
			// 处理库存信息的虚拟子卷号 2018-11-09
			MesCrAnnealM mcam  = new MesCrAnnealM();
			BeanUtils.copyProperties(v_rec_cam, mcam);
			mcam.setMaterial_no_vt(lpmdc.get(0).getObject_no_vt());
			CommonPage<MesCrAnnealM> cp2=new CommonPage<MesCrAnnealM>();			
			cp2.setObject(mcam);
			//调用物流模块（仓库管理）接口，逐一将分条子卷实绩各子卷，插入库存记录（待入库状态）；	
			try{
				//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
				//code 当前工序代码 1 分条/2 开平/3 罩退/4 平整
				String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
				nextP = nextProcessCode;
				if(nextProcessCode==null || "".equals(nextProcessCode)){
					cp2.setMemo1("500203");//成品库					
					//生产订单统计 统计量并修改生产订单状态
				    try{
//				    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,true);
				    }catch(Exception e){
				    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
				    	e.printStackTrace();
				    }
				}else{
					cp2.setMemo1("500202");//在制品库
				}
			}catch(Exception e){
				throw new Exception("获取下道工序异常！"+ e.getMessage());
			}
			//2019-02-21修改
			PlnMaterielDetail pmd_21=new PlnMaterielDetail();
			pmd_21.setObject_no_vt(plp.getObject_no_vt());
			List<PlnMaterielDetail> list_pmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmd_21, 0, 0);
			boolean flag_Ct = false;
			if(list_pmd!=null && list_pmd.size()>0){
				flag_Ct=this.getBean(MesApiDesignInfoImpl.class).getContractType(list_pmd.get(0).getProd_order_no());
			}
			if(flag_Ct){
				cp2.setMemo3("507101");//物料属性，优特钢带
			}
			try{
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doMesIn2(cp2);
				if(!"200".equals(rmValid.getState())){
					throw new Exception("入库出错！"+rmValid.getMsgInfo());
				}
				
				// 写入库存表后去更新生产订单状态：20230909刘侣；
				YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,true);
					
				}
				// end
				
				// 检验委托：如果是最后一道工序才需要送样，去做检验委托：
				// 待判信息发送：如果是最后一道工序（进成品库），那么就给isfinal ： 1， 否则就是：0；
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					
					// 发送检验委托信息：20230909刘侣：最后一道工序才送样
					if (v_rec_cam.getCoil_no() != null && ("B".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1))
							 || "H".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1)))) {
						
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), true, "1");
					} else {
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "1");
					}
					
					// 只有以6开头的订单才去发送检验委托：
					if (ypdQ.getOrderno() != null ) {
						ResultModel rmwt = this.getBean(SlmFundFirstDetailServiceImpl.class).sendToJYWT(v_rec_cam.getCoil_no(), true);
  						if ("500".equals(rmwt.getState())) {
  							throw new Exception(rmwt.getMsgInfo());
  						}
					}
					
					// end
				} else {
					// 非最后一道：
					if (v_rec_cam.getCoil_no() != null && ("B".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1))
							 || "H".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1)))) {
						
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), true, "0");
					} else {
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "0");
					}
				}
				// end
				
				
			}catch(Exception ex){
				ex.printStackTrace();
				throw new Exception("物流入库接口出错！"+ ex.getMessage());
			}
			
			try{
				ResultModel rm = this.getBean(QmsApiServiceImpl.class).doQueryJudegeResult(v_rec_cam.getCoil_no());
				if(rm!=null && rm.getData()!=null && (rm.getData() instanceof JudgeResult)){
					JudgeResult jr=(JudgeResult)rm.getData();
					YdmProductDetail ypd=new YdmProductDetail();
					ypd.setCoilno(v_rec_cam.getCoil_no());
					boolean falgggg=false;
					if(jr.getMarginal_result()!=null){
						ypd.setMarginal_result(jr.getMarginal_result());
						falgggg=true;
					}
					if(jr.getMarginal_result_id()!=null){
						ypd.setMarginal_result_id(jr.getMarginal_result_id());
						falgggg=true;
					}
					if(jr.getMeasure_result()!=null){
						ypd.setMeasure_result(jr.getMeasure_result());
						falgggg=true;
					}
					if(jr.getMeasure_result_id()!=null){
						ypd.setMeasure_result_id(jr.getMeasure_result_id());
						falgggg=true;
					}
					if(jr.getSfd_is_lock()!=null){
						ypd.setSfd_is_lock(jr.getSfd_is_lock());
						falgggg=true;
					}
					if(jr.getSfe_is_lock()!=null){
						ypd.setSfe_is_lock(jr.getSfe_is_lock());
						falgggg=true;
					}
					if(jr.getSfu_is_lock()!=null){
						ypd.setSfu_is_lock(jr.getSfu_is_lock());
						falgggg=true;
					}
					if(jr.getSic_is_lock()!=null){
						ypd.setSic_is_lock(jr.getSic_is_lock());
						falgggg=true;
					}
					if(jr.getSizeResult()!=null){
						ypd.setSizeresult(jr.getSizeResult());
						falgggg=true;
					}
					if(jr.getUd_surface_result()!=null){
						ypd.setUd_surface_result(jr.getUd_surface_result());
						falgggg=true;
					}
					if(jr.getUd_surface_result_id()!=null){
						ypd.setUd_surface_result_id(jr.getUd_surface_result_id());
						falgggg=true;
					}
					if(jr.getUp_surface_result()!=null){
						ypd.setUp_surface_result(jr.getUp_surface_result());
						falgggg=true;
					}
					if(jr.getUp_surface_result_id()!=null){
						ypd.setUp_surface_result_id(jr.getUp_surface_result_id());
						falgggg=true;
					}
					if(jr.getUp_surface_flaw() != null) {
						ypd.setUp_surface_flaw(jr.getUp_surface_flaw());
						falgggg= true;
					}
					if(jr.getUd_surface_flaw() != null) {
						ypd.setUd_surface_flaw(jr.getUd_surface_flaw());
						falgggg= true;
					}
					if(jr.getMarginal_flaw()!= null) {
						ypd.setMarginal_flaw(jr.getMarginal_flaw());
						falgggg= true;
					}
					if(falgggg){
//						this.getMapper(YdmProductDetailMapper.class).update(ypd);
					}
				}
			}catch(Exception e){
				System.out.println("调用质量接口报错");
				e.printStackTrace();
			}
			
			try{
				PlnMaterielDetail pmdq=new PlnMaterielDetail();
				pmdq.setObject_no(v_rec_cam.getMaterial_no());
				pmdq.setObject_no_vt(lpmdc.get(0).getObject_no_vt());
				pmdq.setMaterial_no(v_rec_cam.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmdq.setSub_object_no(v_rec_cam.getCoil_no()); // 子卷号
				// 传入操作时间 2018-06-19
				pmdq.setCreate_time(now);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Relation(pmdq);
				
				// 虚拟母卷
				List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Sum(lpmdq.get(0));
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}
			
			
		    //--(3.9)、修改罩退作业主实绩交工状态																																							
			this.getMapper(MesCrAnnealMMapper.class).doUpdate2(wrk_date,wrk_ord,wrk_grp,username,plp.getMachine_code(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());	    			
			//2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
  					try{
  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
  					}catch(Exception e){
  						
  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){
						
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										//mCrossleo.setMachine_code(sum.getMemo1());
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}
						
						ajsfp.setBatch_no(v_rec_cam.getBatch_no());//轧批号    炉次号
						//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
						List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
						if(list_plnP!=null && list_plnP.size()>0){
							ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
						}
						ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
						//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
						//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
						ajsfp.setHeat_no(v_rec_cam.getBatch_no());//炉号      
						//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
						
						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
						List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
						// 获取工艺路径包含成分或者材质类
						if(judge_Contain_Qcm!=-1){
							ajsfp.setPline_seq((long)judge_Contain_Qcm);
							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();
				}
		    }
		    
		    
		    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
				// 记录成本异动点：20230811刘侣
				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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") ? "分条" : "原料";
				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("YTTH");
				cd.setLocNo("YTTH");
				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("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
		    
		    
			//==========================质量检验委托结束==================================
		    //日志
			
		    MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "交工", username, opr_time, plp.getMaterial_no(), null, null, null, "南方退火炉；下道工序为：" + nextP);
		    this.getMapper(MesOprLogMapper.class).insert(mol);		
		}		
		r.setState("200");
		r.setMsgInfo("交工成功!");
		return r;
	}
		
	/***
	 * 动作处理--取消交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOutOff(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;
		//(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要取消交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}
		//(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			//(2.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(sum.getMemo1());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//    --(2.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(sum.getMemo1());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_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.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(2.5)、验证原料卷对应的罩退主实绩存在，且为“已交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(sum.getMemo1());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()==null || !v_rec_cam.getHand_over_status().equals("1")){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"还未生产交工！");
		    }
		    //(2.6)、调用物流模块接口，验证出口钢卷为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；																																							
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			YdmProductDetail u=new YdmProductDetail();
		    u.setCoilno(v_rec_cam.getCoil_no()); 
		    cp.setObject(u);
			ResultModel rm1 = this.getBean(LmsApiServiceImpl.class).doConfirmWaitIn(cp);
			if(rm1.getState().equals("500")){
				throw new Exception(rm1.getMsgInfo());
			}
		    //取消交工需要先2.8 然后2.7
			 //(2.8)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；	??
			//则调用生产管理的【分条完成——虚拟子卷 挂料接口】按计划执行
			List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			PlnMaterielDetail pmdq=new PlnMaterielDetail();
			pmdq.setObject_no(v_rec_cam.getCoil_no());
			pmdq.setObject_no_vt(lpmd.get(0).getObject_no_vt());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_RelationCancel(pmdq);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}		
			
			// 在库存表记录被删除之前更新生产订单状态：
			// 写入库存表后去更新生产订单状态：20230909刘侣；
			YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
			if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
				this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,false);
			}
			// end
			
		    //(2.7)、调用物流模块接口，删除出口钢卷移库记录及库存实绩（接口由物流模块提供）；																																							
			YdmProductDetail u2=new YdmProductDetail();
			CommonPage<YdmProductDetail> cp3=new CommonPage<YdmProductDetail>();
			u2.setCoilno(v_rec_cam.getCoil_no());
			cp3.setObject(u2);
			ResultModel rm2 = this.getBean(LmsApiServiceImpl.class).doCancelIn(cp3);	
			if(rm1.getState().equals("500")){
				throw new Exception(rm2.getMsgInfo());
			}			
			// 释放虚拟母卷
			PlnMaterielDetail pmdq1=new PlnMaterielDetail();
			pmdq1.setObject_no_vt(v_rec_cam.getMaterial_no_vt());
			pmdq1.setObject_no(v_rec_cam.getMaterial_no());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_SumCancel(pmdq1);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}									
		    //--(2.9)、修改罩退作业主实绩交工状态																																							
		    this.getMapper(MesCrAnnealMMapper.class).doUpdate3(username,sum.getMemo1(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());		    		    
		    //2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
  					try{
  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
  					}catch(Exception e){
  						
  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){
						
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										//mCrossleo.setMachine_code(sum.getMemo1());
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}					
						ajsfp.setBatch_no(v_rec_cam.getBatch_no());//轧批号    炉次号
						//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
						List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
						if(list_plnP!=null && list_plnP.size()>0){
							ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
						}
						ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
						//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
						//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
						ajsfp.setHeat_no(v_rec_cam.getBatch_no());//炉号      
						//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
						
						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
						// 获取工艺路径包含成分或者材质类
						if(judge_Contain_Qcm!=-1){
							ajsfp.setPline_seq((long)judge_Contain_Qcm);
							QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
							qjsprem.setDesign_key(lpp.get(0).getDesign_key());
							qjsprem.setInspection_lot(v_rec_cam.getInspection_lot());
							CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
							sum22.setObject(qjsprem);
							this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
		    }
			//==========================质量检验委托结束==================================
		    String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
			if(nextProcessCode==null || "".equals(nextProcessCode)){
				//生产订单统计 统计量并修改生产订单状态
			    try{
//			    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,false);
			    }catch(Exception e){
			    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
			    	e.printStackTrace();
			    }
			}	
			
			
			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
				// 记录成本异动点：20230811刘侣
				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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 = this.getBean(YdmProductInlistService.class).doQueryTl(ypdM.getCoilno());
				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("YTTH");
				cd.setLocNo("YTTH");
				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("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "取消交工", username, opr_time, plp.getMaterial_no(), null, null, null, (("M0004".equals(plp.getMachine_code()))?"宝信退火炉":"艾伯纳退火炉"));
			this.getMapper(MesOprLogMapper.class).insert(mol);		    
		}		
		r.setState("200");
		r.setMsgInfo("取消交工成功！");
		return r;
	}
	
	/***
	 * 动作处理--取消交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * machine_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOutOff_DG(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要取消交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				r.setState("500");
				r.setMsgInfo("参数错误：机台代码不能为空！");
				return r;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}
		//(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			//(2.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(plp.getMachine_code());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(2.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(plp.getMachine_code());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_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.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(2.5)、验证原料卷对应的罩退主实绩存在，且为“已交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(plp.getMachine_code());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()==null || !v_rec_cam.getHand_over_status().equals("1")){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"还未生产交工！");
		    }
		    //--(2.6)、调用物流模块接口，验证出口钢卷为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；																																							
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			YdmProductDetail u=new YdmProductDetail();
		    u.setCoilno(v_rec_cam.getCoil_no()); 
		    cp.setObject(u);
			ResultModel rm1 = this.getBean(LmsApiServiceImpl.class).doConfirmWaitIn(cp);
			if(rm1.getState().equals("500")){
				//return rm1;
				throw new Exception(rm1.getMsgInfo());
			}
		    //取消交工需要先2.8 然后2.7
			 //--(2.8)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；	??
			//则调用生产管理的【分条完成——虚拟子卷 挂料接口】按计划执行
			List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			PlnMaterielDetail pmdq=new PlnMaterielDetail();
			pmdq.setObject_no(v_rec_cam.getCoil_no());
			pmdq.setObject_no_vt(lpmd.get(0).getObject_no_vt());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_RelationCancel(pmdq);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}				
			
			// 在库存表记录被删除之前更新生产订单状态：
			// 写入库存表后去更新生产订单状态：20230909刘侣；
			YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
			if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
				this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,false);
			}
			// end
			
		    //--(2.7)、调用物流模块接口，删除出口钢卷移库记录及库存实绩（接口由物流模块提供）；																																							
			YdmProductDetail u2=new YdmProductDetail();
			CommonPage<YdmProductDetail> cp3=new CommonPage<YdmProductDetail>();
			u2.setCoilno(v_rec_cam.getCoil_no());
			cp3.setObject(u2);
			ResultModel rm2 = this.getBean(LmsApiServiceImpl.class).doCancelIn(cp3);	
			if(rm1.getState().equals("500")){
				throw new Exception(rm2.getMsgInfo());
			}	
			// 释放虚拟母卷
			PlnMaterielDetail pmdq1=new PlnMaterielDetail();
			pmdq1.setObject_no_vt(v_rec_cam.getMaterial_no_vt());
			pmdq1.setObject_no(v_rec_cam.getMaterial_no());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_SumCancel(pmdq1);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}					
		    //--(2.9)、修改罩退作业主实绩交工状态																																							
		    this.getMapper(MesCrAnnealMMapper.class).doUpdate3(username,plp.getMachine_code(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());		    
		    
		    //2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
  					try{
  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
  					}catch(Exception e){
  						
  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){					
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										//mCrossleo.setMachine_code(sum.getMemo1());
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}
						
						ajsfp.setBatch_no(v_rec_cam.getBatch_no());//轧批号    炉次号
						//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
						List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
						if(list_plnP!=null && list_plnP.size()>0){
							ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
						}
						ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
						//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
						//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
						ajsfp.setHeat_no(v_rec_cam.getBatch_no());//炉号      
						//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
						
						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
						// 获取工艺路径包含成分或者材质类
						if(judge_Contain_Qcm!=-1){
							ajsfp.setPline_seq((long)judge_Contain_Qcm);
							QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
							qjsprem.setDesign_key(lpp.get(0).getDesign_key());
							qjsprem.setInspection_lot(v_rec_cam.getInspection_lot());
							CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
							sum22.setObject(qjsprem);
							this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
		    }
			//==========================质量检验委托结束==================================
		    String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
			if(nextProcessCode==null || "".equals(nextProcessCode)){
				//生产订单统计 统计量并修改生产订单状态
			    try{
//			    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,false);
			    }catch(Exception e){
			    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
			    	e.printStackTrace();
			    }
			}
			
			
			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
				// 记录成本异动点：20230811刘侣
				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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("YTTH");
				cd.setLocNo("YTTH");
				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("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "取消交工", username, opr_time, plp.getMaterial_no(), null, null, null, "南方退火炉");
			this.getMapper(MesOprLogMapper.class).insert(mol);	    
		}		
		r.setState("200");
		r.setMsgInfo("取消交工成功！");
		return r;
	}
	
	
	/***
	 * 动作处理--交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录班组
	 * memo3:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOffNew(CommonPage<PlnAnnealPlan> 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 nextP = "";
		
		Integer v_cnt;
		DateFormat dftwo = new SimpleDateFormat("yyyy-MM-dd");
		//--(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			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;
		}		
		// --优特钢目前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;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}	
		//（2）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		String dbTime=rmDb.getData().toString().substring(11);
		String wrk_date=null,wrk_ord=null,wrk_grp=null;
		if("200".equals(rmDb.getState())){
			dbTime=rmDb.getData().toString().substring(11);
			wrk_date=rmDb.getData().toString().substring(0,10);			
			if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
				wrk_ord="1";
			}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
				wrk_ord="2";
			}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
				wrk_ord="1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date;
				try {
					date = formatYmd.parse(wrk_date);
				} catch (Exception e) {
					throw new Exception("获取数据库时间失败，请稍后重试");
				}
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
				wrk_date=formatYmd.format(c.getTime());
			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}
		//（2.4）、根据计算的日期班次，获取交接班记录的班组
		MesShiftM msm=new MesShiftM();
		if(sum.getMemo1().equals("M0009")){
			msm.setMachine_code("M0005");
		}else{
			msm.setMachine_code(sum.getMemo1());
		}
		msm.setWrk_date(wrk_date);
		msm.setWrk_ord(wrk_ord);
		v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
		if(v_cnt<=0){
			wrk_grp=sum.getMemo2();//   --暂无交接班记录，则使用前端传入的班组代码
		}else{
			// 否则获取交接班记录中的班组
			List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
			wrk_grp=lmsm.get(0).getWrk_grp();
		}
		// (3)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			// (3.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(sum.getMemo1());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(3.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(sum.getMemo1());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
						+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
			}			
			//(3.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原料卷虚拟物料信息不存在！");
			}
			//(3.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(3.5)、验证原料卷对应的罩退主实绩存在，且为“未交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(sum.getMemo1());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()!=null && !v_rec_cam.getHand_over_status().equals("0")){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能重复操作！");
		    }
			//    --(3.6)、验证实绩中必要的数据项都填写 
			if(v_rec_cam.getFurnace_no()==null){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"炉座号为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getBatch_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉次号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getIn_fur_seq()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉内序号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_date()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料日期为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_ord()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班次为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_grp()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班组为空，不能交工，请先填写完整并保存！");
		    }
			if(v_rec_cam.getCharge_time()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"生产开始时间为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getCoil_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷号为空，不能交工，数据异常，请联系系统管理员！");
		    }
		    if(v_rec_cam.getCoil_act_wgt()==null || v_rec_cam.getCoil_act_wgt()<0){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷重量为空或小于零，不能交工，请先填写完整并保存！");
		    }
		    //生产结束时间
			if(v_rec_cam.getDischarge_time()==null){
				v_rec_cam.setDischarge_time(new Date());
			}
			 
			//--(2.11)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			//String v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			String v_coil_no=null;
			String v_leo="";
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
					}
				}else{
					v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
				}
				
			}else{
				v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			}
			if(v_coil_no!=null){
				//    --(2.11.1)、获取当前起始流水号
				v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb6(v_coil_no,v_rec_cam.getSchedule_no(),v_rec_cam.getMaterial_no());
				if(v_cnt==null){
					v_cnt=1;
				}else if(v_cnt>99){
					String v_message="作业计划号{"+v_rec_cam.getSchedule_no()+"} 原料卷号{"+v_rec_cam.getMaterial_no()+"} 出口钢卷号超出规则范围，流水号超出最大值99！";
					r.setState("500");
			    	r.setMsgInfo(v_message);
					return r;
				}
				//--(2.11.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																						
				v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			}
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_rec_cam.setCoil_no(v_coil_no);
					}					
				}else{
					v_rec_cam.setCoil_no(v_coil_no);
				}
				
			}
			v_rec_cam.setDischarge_date(dftwo.format(now));//交工日期当产出日期
		    this.getMapper(MesCrAnnealMMapper.class).update(v_rec_cam);
						
		    List<PlnMaterielDetail> lpmdc=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			if (Utils.isEmpty(lpmdc)) {
				throw new Exception("未找到虚拟子卷信息!");
			}			
			// 处理库存信息的虚拟子卷号 2018-11-09
			MesCrAnnealM mcam  = new MesCrAnnealM();
			BeanUtils.copyProperties(v_rec_cam, mcam);
			mcam.setMaterial_no_vt(lpmdc.get(0).getObject_no_vt());
			
		    //--(3.7)、调用物流模块接口，执行出口钢卷入库相关操作（接口由物流模块提供）；																																							
			YdmProductDetail p=new YdmProductDetail();
			p.setCoilno(v_rec_cam.getCoil_no());
			//入库的信息不全......
			CommonPage<MesCrAnnealM> cp2=new CommonPage<MesCrAnnealM>();
			
			cp2.setObject(mcam);
			//调用物流模块（仓库管理）接口，逐一将分条子卷实绩各子卷，插入库存记录（待入库状态）；	
			try{
				//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
				String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
				nextP = nextProcessCode;
				if(nextProcessCode==null || "".equals(nextProcessCode)){
					cp2.setMemo1("500203");//成品库					
					//生产订单统计 统计量并修改生产订单状态
				    try{
//				    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,true);
				    }catch(Exception e){
				    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
				    	e.printStackTrace();
				    }				
				}else{
					cp2.setMemo1("500202");//在制品库
				}
			}catch(Exception e){
				throw new Exception("获取下道工序异常！"+ e.getMessage());
			}
			//2019-02-21修改
			PlnMaterielDetail pmd_21=new PlnMaterielDetail();
			pmd_21.setObject_no_vt(plp.getObject_no_vt());
			List<PlnMaterielDetail> list_pmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmd_21, 0, 0);
			boolean flag_Ct = false;
			if(list_pmd!=null && list_pmd.size()>0){
				flag_Ct=this.getBean(MesApiDesignInfoImpl.class).getContractType(list_pmd.get(0).getProd_order_no());
			}
			if(flag_Ct){
				cp2.setMemo3("507101");//物料属性，优特钢带
			}			
			try{
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doMesIn2(cp2);
				if(!"200".equals(rmValid.getState())){
					throw new Exception("入库出错！"+rmValid.getMsgInfo());
				}
				
				// 写入库存表后去更新生产订单状态：20230909刘侣；
				YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,true);
					// end
				}
				
				// 检验委托：如果是最后一道工序才需要送样，去做检验委托：
				// 待判信息发送：如果是最后一道工序（进成品库），那么就给isfinal ： 1， 否则就是：0；
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					
					// 发送检验委托信息：20230909刘侣：最后一道工序才送样
					if (v_rec_cam.getCoil_no() != null && ("B".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1))
							 || "H".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1)))) {
						
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), true, "1");
					} else {
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "1");
					}
					
					// 只有以6开头的订单才去发送检验委托：
					if (ypdQ.getOrderno() != null ) {
						ResultModel rmwt = this.getBean(SlmFundFirstDetailServiceImpl.class).sendToJYWT(v_rec_cam.getCoil_no(), true);
  						if ("500".equals(rmwt.getState())) {
  							throw new Exception(rmwt.getMsgInfo());
  						}
					}
					
					// end
				} else {
					// 非最后一道：
					if (v_rec_cam.getCoil_no() != null && ("B".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1))
							 || "H".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1)))) {
						
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), true, "0");
					} else {
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "0");
					}
				}
				// end
				
				
			}catch(Exception ex){
				ex.printStackTrace();
				throw new Exception("物流入库接口出错！"+ ex.getMessage());
			}
						
//			try{
//				ResultModel rm = this.getBean(QmsApiServiceImpl.class).doQueryJudegeResult(v_rec_cam.getCoil_no());
//				if(rm!=null && rm.getData()!=null && (rm.getData() instanceof JudgeResult)){
//					JudgeResult jr=(JudgeResult)rm.getData();
//					YdmProductDetail ypd=new YdmProductDetail();
//					ypd.setCoilno(v_rec_cam.getCoil_no());
//					boolean falgggg=false;
//					if(jr.getMarginal_result()!=null){
//						ypd.setMarginal_result(jr.getMarginal_result());
//						falgggg=true;
//					}
//					if(jr.getMarginal_result_id()!=null){
//						ypd.setMarginal_result_id(jr.getMarginal_result_id());
//						falgggg=true;
//					}
//					if(jr.getMeasure_result()!=null){
//						ypd.setMeasure_result(jr.getMeasure_result());
//						falgggg=true;
//					}
//					if(jr.getMeasure_result_id()!=null){
//						ypd.setMeasure_result_id(jr.getMeasure_result_id());
//						falgggg=true;
//					}
//					if(jr.getSfd_is_lock()!=null){
//						ypd.setSfd_is_lock(jr.getSfd_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSfe_is_lock()!=null){
//						ypd.setSfe_is_lock(jr.getSfe_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSfu_is_lock()!=null){
//						ypd.setSfu_is_lock(jr.getSfu_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSic_is_lock()!=null){
//						ypd.setSic_is_lock(jr.getSic_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSizeResult()!=null){
//						ypd.setSizeresult(jr.getSizeResult());
//						falgggg=true;
//					}
//					if(jr.getUd_surface_result()!=null){
//						ypd.setUd_surface_result(jr.getUd_surface_result());
//						falgggg=true;
//					}
//					if(jr.getUd_surface_result_id()!=null){
//						ypd.setUd_surface_result_id(jr.getUd_surface_result_id());
//						falgggg=true;
//					}
//					if(jr.getUp_surface_result()!=null){
//						ypd.setUp_surface_result(jr.getUp_surface_result());
//						falgggg=true;
//					}
//					if(jr.getUp_surface_result_id()!=null){
//						ypd.setUp_surface_result_id(jr.getUp_surface_result_id());
//						falgggg=true;
//					}
//					if(jr.getUp_surface_flaw() != null) {
//						ypd.setUp_surface_flaw(jr.getUp_surface_flaw());
//						falgggg= true;
//					}
//					if(jr.getUd_surface_flaw() != null) {
//						ypd.setUd_surface_flaw(jr.getUd_surface_flaw());
//						falgggg= true;
//					}
//					if(jr.getMarginal_flaw()!= null) {
//						ypd.setMarginal_flaw(jr.getMarginal_flaw());
//						falgggg= true;
//					}
//					if(falgggg){
//						this.getMapper(YdmProductDetailMapper.class).update(ypd);
//					}
//				}
//			}catch(Exception e){
//				System.out.println("调用质量接口报错");
//				e.printStackTrace();
//			}
						
		    //--(3.8)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；
			try{
				PlnMaterielDetail pmdq=new PlnMaterielDetail();
				pmdq.setObject_no(v_rec_cam.getMaterial_no());
				pmdq.setObject_no_vt(lpmdc.get(0).getObject_no_vt());
				pmdq.setMaterial_no(v_rec_cam.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmdq.setSub_object_no(v_rec_cam.getCoil_no()); // 子卷号
				// 传入操作时间 2018-06-19
				pmdq.setCreate_time(now);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Relation(pmdq);
				
				// 虚拟母卷
				List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Sum(lpmdq.get(0));
			}catch(Exception e){
				e.printStackTrace();
				throw new Exception("计划接口出错！"+ e.getMessage());
			}
					
		    //--(3.9)、修改罩退作业主实绩交工状态																																							
			this.getMapper(MesCrAnnealMMapper.class).doUpdate2(wrk_date,wrk_ord,wrk_grp,username,sum.getMemo1(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());
		
			//2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
	  					try{
	  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
	  					}catch(Exception e){
	  						
	  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){
						
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}
						
//						ajsfp.setBatch_no(v_rec_cam.getBatch_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.setHeat_no(v_rec_cam.getBatch_no());//炉号      
//						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
//						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
//						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
//						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
//						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
//						
//						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
//						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
//						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
//						List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
//						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
//						// 获取工艺路径包含成分或者材质类
//						if(judge_Contain_Qcm!=-1){
//							ajsfp.setPline_seq((long)judge_Contain_Qcm);
//							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.getMsgInfo());
//							}
//						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
		    }
		    
		    
		    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
			    // 记录成本异动点：20230811刘侣
	 			YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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") ? "分条" : "原料";
				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("YTTH");
				cd.setLocNo("YTTH");
				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("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
		    
		    
			//==========================质量检验委托结束==================================
		 	//日志
		    MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "交工", username, opr_time, plp.getMaterial_no(), null, null, null, lcbm.get(0).getMachine_name() + "；下道工序为：" + nextP);
		    this.getMapper(MesOprLogMapper.class).insert(mol);		    
		}	
		r.setState("200");
		r.setMsgInfo("交工成功!");
		return r;
	}
	
	
	/***
	 * 动作处理--交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * machine_code:机台代码
	 * memo2:登录班组
	 * memo3:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOff_DGNew(CommonPage<PlnAnnealPlan> 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 nextP = "";
		
		Integer v_cnt;
		DateFormat dftwo = new SimpleDateFormat("yyyy-MM-dd");
		// --优特钢目前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;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				r.setState("500");
				r.setMsgInfo("参数错误：机台代码不能为空！");
				return r;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}		
		//  --（2）、根据当前时刻，计算日期班次
		ResultModel rmDb=this.getBean(PbModelDbServiceImpl.class).findDbTime();
		String dbTime=rmDb.getData().toString().substring(11);
		String wrk_date=null,wrk_ord=null,wrk_grp=null;
		if("200".equals(rmDb.getState())){
			dbTime=rmDb.getData().toString().substring(11);
			wrk_date=rmDb.getData().toString().substring(0,10);			
			if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
				wrk_ord="1";
			}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
				wrk_ord="2";
			}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
				wrk_ord="1";
				SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
				Date date;
				try {
					date = formatYmd.parse(wrk_date);
				} catch (Exception e) {
					throw new Exception("获取数据库时间失败，请稍后重试");
				}
				Calendar c = Calendar.getInstance();  
    	        c.setTime(date);  
    	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
				wrk_date=formatYmd.format(c.getTime());
			}
		}else{
			throw new Exception("获取数据库时间失败！请稍后重试");
		}
		//  --（2.4）、根据计算的日期班次，获取交接班记录的班组
		MesShiftM msm=new MesShiftM();
		msm.setMachine_code("M0005");
		msm.setWrk_date(wrk_date);
		msm.setWrk_ord(wrk_ord);
		v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
		if(v_cnt<=0){
			wrk_grp=sum.getMemo2();//   --暂无交接班记录，则使用前端传入的班组代码
		}else{
			//    --否则获取交接班记录中的班组
			List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
			wrk_grp=lmsm.get(0).getWrk_grp();
		}
		
		// (3)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){			
			//  --（2.1)、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
			ComBaseMachine machine2 = new ComBaseMachine();
			machine2.setMachine_code(plp.getMachine_code());
			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;
			}			
			//(3.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(plp.getMachine_code());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(3.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(plp.getMachine_code());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n虚拟卷号："+plp.getObject_no_vt()+""
						+ "\n原料卷号："+plp.getMaterial_no()+"\n作业计划明细记录不存在！");
			}		
			//--(3.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原料卷虚拟物料信息不存在！");
			}
			//--(3.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//--(3.5)、验证原料卷对应的罩退主实绩存在，且为“未交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(plp.getMachine_code());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()!=null && !v_rec_cam.getHand_over_status().equals("0")){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"当前已生产交工，不能重复操作！");
		    }
			//    --(3.6)、验证实绩中必要的数据项都填写 
			if(v_rec_cam.getFurnace_no()==null){
				throw new Exception("原料卷号："+plp.getMaterial_no()+"炉座号为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getBatch_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉次号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getIn_fur_seq()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"炉内序号为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_date()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料日期为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_ord()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班次为空，不能交工，请先填写完整并保存！");
		    }
		    if(v_rec_cam.getCharge_grp()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"投料班组为空，不能交工，请先填写完整并保存！");
		    }
			if(v_rec_cam.getCharge_time()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"生产开始时间为空，不能交工，请先填写完整并保存！");
			}
		    if(v_rec_cam.getCoil_no()==null){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷号为空，不能交工，数据异常，请联系系统管理员！");
		    }
		    if(v_rec_cam.getCoil_act_wgt()==null || v_rec_cam.getCoil_act_wgt()<0){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"产出卷重量为空或小于零，不能交工，请先填写完整并保存！");
		    }
		    //生产结束时间
			if(v_rec_cam.getDischarge_time()==null){
				v_rec_cam.setDischarge_time(new Date());
			}
			
			//(2.11)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			String v_coil_no=null;
			String v_leo="";
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
					}
				}else{
					v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_rec_cam.getFurnace_no(), 2, "0");
				}				
			}else{
				v_coil_no = v_rec_cam.getMaterial_no().substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			}
			
			if(v_coil_no!=null){
				//--(2.11.1)、获取当前起始流水号
				v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb6(v_coil_no,v_rec_cam.getSchedule_no(),v_rec_cam.getMaterial_no());
				if(v_cnt==null){
					v_cnt=1;
				}else if(v_cnt>99){
					String v_message="作业计划号{"+v_rec_cam.getSchedule_no()+"} 原料卷号{"+v_rec_cam.getMaterial_no()+"} 出口钢卷号超出规则范围，流水号超出最大值99！";
					r.setState("500");
			    	r.setMsgInfo(v_message);
					return r;
				}
				//--(2.11.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																						
				v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			}
			
			if(v_rec_cam.getFurnace_no()!=null && !"".equals(v_rec_cam.getFurnace_no())){
				String v_syh=lpad(v_rec_cam.getFurnace_no(), 2, "0");
				if(v_rec_cam.getCoil_no()!=null){
					v_leo=v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-4, v_rec_cam.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_rec_cam.setCoil_no(v_coil_no);
					}					
				}else{
					v_rec_cam.setCoil_no(v_coil_no);
				}
				
			}
			v_rec_cam.setDischarge_date(dftwo.format(now));//20210628交工当前时间当做产出时间
		    this.getMapper(MesCrAnnealMMapper.class).update(v_rec_cam);		
		    
		    List<PlnMaterielDetail> lpmdc=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			if (Utils.isEmpty(lpmdc)) {
				throw new Exception("未找到虚拟子卷信息!");
			}
			
			// 处理库存信息的虚拟子卷号 2018-11-09
			MesCrAnnealM mcam  = new MesCrAnnealM();
			BeanUtils.copyProperties(v_rec_cam, mcam);
			mcam.setMaterial_no_vt(lpmdc.get(0).getObject_no_vt());
			CommonPage<MesCrAnnealM> cp2=new CommonPage<MesCrAnnealM>();			
			cp2.setObject(mcam);
			//调用物流模块（仓库管理）接口，逐一将分条子卷实绩各子卷，插入库存记录（待入库状态）；	
			try{
				//下道工序不为空，入库仓库为中间品库，为空（最后一道工序了），就如成品库         ？？？？
				//code 当前工序代码 1 分条/2 开平/3 罩退/4 平整
				String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
				nextP = nextProcessCode;
				if(nextProcessCode==null || "".equals(nextProcessCode)){
					cp2.setMemo1("500203");//成品库					
					//生产订单统计 统计量并修改生产订单状态
				    try{
//				    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,true);
				    }catch(Exception e){
				    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
				    	e.printStackTrace();
				    }
				}else{
					cp2.setMemo1("500202");//在制品库
				}
			}catch(Exception e){
				throw new Exception("获取下道工序异常！"+ e.getMessage());
			}
			//2019-02-21修改
			PlnMaterielDetail pmd_21=new PlnMaterielDetail();
			pmd_21.setObject_no_vt(plp.getObject_no_vt());
			List<PlnMaterielDetail> list_pmd = this.getMapper(PlnMaterielDetailMapper.class).find(pmd_21, 0, 0);
			boolean flag_Ct = false;
			if(list_pmd!=null && list_pmd.size()>0){
				flag_Ct=this.getBean(MesApiDesignInfoImpl.class).getContractType(list_pmd.get(0).getProd_order_no());
			}
			if(flag_Ct){
				cp2.setMemo3("507101");//物料属性，优特钢带
			}
			try{
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doMesIn2(cp2);
				if(!"200".equals(rmValid.getState())){
					throw new Exception("入库出错！"+rmValid.getMsgInfo());
				}
				
				// 写入库存表后去更新生产订单状态：20230909刘侣；
				YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,true);
					
				}
				// end
				
				// 检验委托：如果是最后一道工序才需要送样，去做检验委托：
				// 待判信息发送：如果是最后一道工序（进成品库），那么就给isfinal ： 1， 否则就是：0；
				if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
					
					// 发送检验委托信息：20230909刘侣：最后一道工序才送样
					if (v_rec_cam.getCoil_no() != null && ("B".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1))
							 || "H".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1)))) {
						
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), true, "1");
					} else {
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "1");
					}
					
					// 只有以6开头的订单才去发送检验委托：
					if (ypdQ.getOrderno() != null ) {
						ResultModel rmwt = this.getBean(SlmFundFirstDetailServiceImpl.class).sendToJYWT(v_rec_cam.getCoil_no(), true);
  						if ("500".equals(rmwt.getState())) {
  							throw new Exception(rmwt.getMsgInfo());
  						}
					}
					
					// end
				} else {
					// 非最后一道：
					if (v_rec_cam.getCoil_no() != null && ("B".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1))
							 || "H".equals(v_rec_cam.getCoil_no().substring(v_rec_cam.getCoil_no().length()-1)))) {
						
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), true, "0");
					} else {
						this.getBean(SlmFundFirstDetailServiceImpl.class).sendToTHPD(v_rec_cam.getCoil_no(), false, "0");
					}
				}
				// end
				
				
			}catch(Exception ex){
				ex.printStackTrace();
				throw new Exception("物流入库接口出错！"+ ex.getMessage());
			}
			
			try{
//				ResultModel rm = this.getBean(QmsApiServiceImpl.class).doQueryJudegeResult(v_rec_cam.getCoil_no());
//				if(rm!=null && rm.getData()!=null && (rm.getData() instanceof JudgeResult)){
//					JudgeResult jr=(JudgeResult)rm.getData();
//					YdmProductDetail ypd=new YdmProductDetail();
//					ypd.setCoilno(v_rec_cam.getCoil_no());
//					boolean falgggg=false;
//					if(jr.getMarginal_result()!=null){
//						ypd.setMarginal_result(jr.getMarginal_result());
//						falgggg=true;
//					}
//					if(jr.getMarginal_result_id()!=null){
//						ypd.setMarginal_result_id(jr.getMarginal_result_id());
//						falgggg=true;
//					}
//					if(jr.getMeasure_result()!=null){
//						ypd.setMeasure_result(jr.getMeasure_result());
//						falgggg=true;
//					}
//					if(jr.getMeasure_result_id()!=null){
//						ypd.setMeasure_result_id(jr.getMeasure_result_id());
//						falgggg=true;
//					}
//					if(jr.getSfd_is_lock()!=null){
//						ypd.setSfd_is_lock(jr.getSfd_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSfe_is_lock()!=null){
//						ypd.setSfe_is_lock(jr.getSfe_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSfu_is_lock()!=null){
//						ypd.setSfu_is_lock(jr.getSfu_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSic_is_lock()!=null){
//						ypd.setSic_is_lock(jr.getSic_is_lock());
//						falgggg=true;
//					}
//					if(jr.getSizeResult()!=null){
//						ypd.setSizeresult(jr.getSizeResult());
//						falgggg=true;
//					}
//					if(jr.getUd_surface_result()!=null){
//						ypd.setUd_surface_result(jr.getUd_surface_result());
//						falgggg=true;
//					}
//					if(jr.getUd_surface_result_id()!=null){
//						ypd.setUd_surface_result_id(jr.getUd_surface_result_id());
//						falgggg=true;
//					}
//					if(jr.getUp_surface_result()!=null){
//						ypd.setUp_surface_result(jr.getUp_surface_result());
//						falgggg=true;
//					}
//					if(jr.getUp_surface_result_id()!=null){
//						ypd.setUp_surface_result_id(jr.getUp_surface_result_id());
//						falgggg=true;
//					}
//					if(jr.getUp_surface_flaw() != null) {
//						ypd.setUp_surface_flaw(jr.getUp_surface_flaw());
//						falgggg= true;
//					}
//					if(jr.getUd_surface_flaw() != null) {
//						ypd.setUd_surface_flaw(jr.getUd_surface_flaw());
//						falgggg= true;
//					}
//					if(jr.getMarginal_flaw()!= null) {
//						ypd.setMarginal_flaw(jr.getMarginal_flaw());
//						falgggg= true;
//					}
//					if(falgggg){
//						this.getMapper(YdmProductDetailMapper.class).update(ypd);
//					}
//				}
			}catch(Exception e){
				System.out.println("调用质量接口报错");
				e.printStackTrace();
			}
			
			try{
				PlnMaterielDetail pmdq=new PlnMaterielDetail();
				pmdq.setObject_no(v_rec_cam.getMaterial_no());
				pmdq.setObject_no_vt(lpmdc.get(0).getObject_no_vt());
				pmdq.setMaterial_no(v_rec_cam.getMaterial_no());//投料卷号 material_no   由页面交工按钮传入
				pmdq.setSub_object_no(v_rec_cam.getCoil_no()); // 子卷号
				// 传入操作时间 2018-06-19
				pmdq.setCreate_time(now);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Relation(pmdq);
				
				// 虚拟母卷
				List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_Sum(lpmdq.get(0));
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}
			
			
		    //--(3.9)、修改罩退作业主实绩交工状态																																							
			this.getMapper(MesCrAnnealMMapper.class).doUpdate2(wrk_date,wrk_ord,wrk_grp,username,plp.getMachine_code(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());	    			
			//2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
  					try{
  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
  					}catch(Exception e){
  						
  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){
						
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										//mCrossleo.setMachine_code(sum.getMemo1());
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}
						
//						ajsfp.setBatch_no(v_rec_cam.getBatch_no());//轧批号    炉次号
//						//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
//						List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
//						if(list_plnP!=null && list_plnP.size()>0){
//							ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
//						}
//						ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
//						//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
//						//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
//						ajsfp.setHeat_no(v_rec_cam.getBatch_no());//炉号      
//						//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
//						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
//						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
//						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
//						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
//						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
//						
//						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
//						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
//						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
//						List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
//						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
//						// 获取工艺路径包含成分或者材质类
//						if(judge_Contain_Qcm!=-1){
//							ajsfp.setPline_seq((long)judge_Contain_Qcm);
//							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();
				}
		    }
		    
		    
		    String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
				// 记录成本异动点：20230811刘侣
				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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") ? "分条" : "原料";
				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("YTTH");
				cd.setLocNo("YTTH");
				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("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
		    
		    
			//==========================质量检验委托结束==================================
		    //日志
			
		    MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "交工", username, opr_time, plp.getMaterial_no(), null, null, null, "南方退火炉；下道工序为：" + nextP);
		    this.getMapper(MesOprLogMapper.class).insert(mol);		
		}		
		r.setState("200");
		r.setMsgInfo("交工成功!");
		return r;
	}
		
	/***
	 * 动作处理--取消交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * memo1:mch_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOutOffNew(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;
		//(1)、验证前端传入参数的基本有效性
		if(sum.getMemo1()==null || sum.getMemo1().length()<=0){
			r.setMsgInfo("参数错误：机台代码不能为空！");
			r.setState("500");
			return r;
		}
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要取消交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}
		//(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			//(2.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(sum.getMemo1());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//    --(2.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(sum.getMemo1());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+sum.getMemo1()+"\n作业计划号："+plp.getAn_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.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(2.5)、验证原料卷对应的罩退主实绩存在，且为“已交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(sum.getMemo1());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()==null || !v_rec_cam.getHand_over_status().equals("1")){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"还未生产交工！");
		    }
		    //(2.6)、调用物流模块接口，验证出口钢卷为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；																																							
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			YdmProductDetail u=new YdmProductDetail();
		    u.setCoilno(v_rec_cam.getCoil_no()); 
		    cp.setObject(u);
			ResultModel rm1 = this.getBean(LmsApiServiceImpl.class).doConfirmWaitIn(cp);
			if(rm1.getState().equals("500")){
				throw new Exception(rm1.getMsgInfo());
			}
		    //取消交工需要先2.8 然后2.7
			 //(2.8)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；	??
			//则调用生产管理的【分条完成——虚拟子卷 挂料接口】按计划执行
			List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			PlnMaterielDetail pmdq=new PlnMaterielDetail();
			pmdq.setObject_no(v_rec_cam.getCoil_no());
			pmdq.setObject_no_vt(lpmd.get(0).getObject_no_vt());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_RelationCancel(pmdq);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}		
			
			// 在库存表记录被删除之前更新生产订单状态：
			// 写入库存表后去更新生产订单状态：20230909刘侣；
			YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
			if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
				this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,false);
			}
			// end
			
		    //(2.7)、调用物流模块接口，删除出口钢卷移库记录及库存实绩（接口由物流模块提供）；																																							
			YdmProductDetail u2=new YdmProductDetail();
			CommonPage<YdmProductDetail> cp3=new CommonPage<YdmProductDetail>();
			u2.setCoilno(v_rec_cam.getCoil_no());
			cp3.setObject(u2);
			ResultModel rm2 = this.getBean(LmsApiServiceImpl.class).doCancelIn(cp3);	
			if(rm1.getState().equals("500")){
				throw new Exception(rm2.getMsgInfo());
			}			
			// 释放虚拟母卷
			PlnMaterielDetail pmdq1=new PlnMaterielDetail();
			pmdq1.setObject_no_vt(v_rec_cam.getMaterial_no_vt());
			pmdq1.setObject_no(v_rec_cam.getMaterial_no());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_SumCancel(pmdq1);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}									
		    //--(2.9)、修改罩退作业主实绩交工状态																																							
		    this.getMapper(MesCrAnnealMMapper.class).doUpdate3(username,sum.getMemo1(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());		    		    
		    //2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
  					try{
  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
  					}catch(Exception e){
  						
  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){
						
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										//mCrossleo.setMachine_code(sum.getMemo1());
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}					
//						ajsfp.setBatch_no(v_rec_cam.getBatch_no());//轧批号    炉次号
//						//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
//						List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
//						if(list_plnP!=null && list_plnP.size()>0){
//							ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
//						}
//						ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
//						//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
//						//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
//						ajsfp.setHeat_no(v_rec_cam.getBatch_no());//炉号      
//						//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
//						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
//						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
//						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
//						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
//						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
//						
//						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
//						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
//						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
//						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
//						// 获取工艺路径包含成分或者材质类
//						if(judge_Contain_Qcm!=-1){
//							ajsfp.setPline_seq((long)judge_Contain_Qcm);
//							QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
//							qjsprem.setDesign_key(lpp.get(0).getDesign_key());
//							qjsprem.setInspection_lot(v_rec_cam.getInspection_lot());
//							CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
//							sum22.setObject(qjsprem);
//							this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
//						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
		    }
			//==========================质量检验委托结束==================================
		    String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
			if(nextProcessCode==null || "".equals(nextProcessCode)){
				//生产订单统计 统计量并修改生产订单状态
			    try{
//			    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,false);
			    }catch(Exception e){
			    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
			    	e.printStackTrace();
			    }
			}	
			
			
			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
				// 记录成本异动点：20230811刘侣
				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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 = this.getBean(YdmProductInlistService.class).doQueryTl(ypdM.getCoilno());
				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("YTTH");
				cd.setLocNo("YTTH");
				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("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "取消交工", username, opr_time, plp.getMaterial_no(), null, null, null, (("M0004".equals(plp.getMachine_code()))?"宝信退火炉":"艾伯纳退火炉"));
			this.getMapper(MesOprLogMapper.class).insert(mol);		    
		}		
		r.setState("200");
		r.setMsgInfo("取消交工成功！");
		return r;
	}
	
	/***
	 * 动作处理--取消交工按钮   
	 * objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * machine_code机台代码
	 * memo2:登录用户名
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel signOutOff_DGNew(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;
		if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
			r.setState("500");
			r.setMsgInfo("参数错误：未指定需要取消交工的原料卷信息！");
			return r;
		}
		for(PlnAnnealPlan plp: sum.getObjectList()){
			if(plp.getMachine_code()==null || "".equals(plp.getMachine_code())){
				r.setState("500");
				r.setMsgInfo("参数错误：机台代码不能为空！");
				return r;
			}
			if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
				r.setState("500");
				r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
				return r;
			}
		}
		//(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
		for(PlnAnnealPlan plp: sum.getObjectList()){
			//(2.1)、验证罩退作业计划主记录存在
			PlnAnnealPlan pcp=new PlnAnnealPlan();
			pcp.setMachine_code(plp.getMachine_code());
			pcp.setAn_plan_no(plp.getAn_plan_no());
			int count = this.getMapper(PlnAnnealPlanMapper.class).count(pcp);
			if (count<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_plan_no()+"\n作业计划主记录不存在！");
			}
			//(2.2)、验证罩退作业计划明细记录存在
			PlnAnnealPlanDetail pcpd=new PlnAnnealPlanDetail();
			pcpd.setMachine_code(plp.getMachine_code());
			pcpd.setAn_plan_no(plp.getAn_plan_no());
			pcpd.setObject_no_vt(plp.getObject_no_vt());
			pcpd.setObject_no(plp.getMaterial_no());
			int count2 = this.getMapper(PlnAnnealPlanDetailMapper.class).count(pcpd);
			if (count2<=0) {
				throw new Exception("机台代码："+plp.getMachine_code()+"\n作业计划号："+plp.getAn_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.4)、验证虚拟物料表中，出口卷虚拟物料信息存在
			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出口卷虚拟物料信息不存在！");
			}
			//(2.5)、验证原料卷对应的罩退主实绩存在，且为“已交工”状态
			MesCrAnnealM mCross = new MesCrAnnealM();
			mCross.setMachine_code(plp.getMachine_code());
			mCross.setSchedule_no(plp.getAn_plan_no());
			mCross.setMaterial_no_vt(plp.getObject_no_vt());
			mCross.setMaterial_no(plp.getMaterial_no());
			v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
			if (v_cnt<=0) {
				throw new Exception("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
			}
		    List<MesCrAnnealM> lmcam = this.getMapper(MesCrAnnealMMapper.class).find(mCross, 0, 0);
		    MesCrAnnealM v_rec_cam =lmcam.get(0);
		    if(v_rec_cam.getHand_over_status()==null || !v_rec_cam.getHand_over_status().equals("1")){
		    	throw new Exception("原料卷号："+plp.getMaterial_no()+"还未生产交工！");
		    }
		    //--(2.6)、调用物流模块接口，验证出口钢卷为待入库状态（可撤销或删除库存数据），否则，返回错误信息到前端，结束操作（接口由物流模块提供）；																																							
			CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
			YdmProductDetail u=new YdmProductDetail();
		    u.setCoilno(v_rec_cam.getCoil_no()); 
		    cp.setObject(u);
			ResultModel rm1 = this.getBean(LmsApiServiceImpl.class).doConfirmWaitIn(cp);
			if(rm1.getState().equals("500")){
				//return rm1;
				throw new Exception(rm1.getMsgInfo());
			}
		    //取消交工需要先2.8 然后2.7
			 //--(2.8)、调用生产管理接口，执行作业计划、原料卷、出口钢卷相关进程状态处理逻辑（接口由生产管理模块提供）；	??
			//则调用生产管理的【分条完成——虚拟子卷 挂料接口】按计划执行
			List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "mat_object_no_vt = '"+v_rec_cam.getMaterial_no_vt()+"' and nvl(invalid_flg,0) = '0'", null, 0, 1);
			PlnMaterielDetail pmdq=new PlnMaterielDetail();
			pmdq.setObject_no(v_rec_cam.getCoil_no());
			pmdq.setObject_no_vt(lpmd.get(0).getObject_no_vt());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_RelationCancel(pmdq);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}				
			
			// 在库存表记录被删除之前更新生产订单状态：
			// 写入库存表后去更新生产订单状态：20230909刘侣；
			YdmProductDetail ypdQ = this.getMapper(YdmProductDetailMapper.class).doFind(v_rec_cam.getCoil_no(), null);
			if (ypdQ != null && "500203".equals(ypdQ.getStorageattr())) {
				this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(ypdQ.getCoilno(),1,false);
			}
			// end
			
		    //--(2.7)、调用物流模块接口，删除出口钢卷移库记录及库存实绩（接口由物流模块提供）；																																							
			YdmProductDetail u2=new YdmProductDetail();
			CommonPage<YdmProductDetail> cp3=new CommonPage<YdmProductDetail>();
			u2.setCoilno(v_rec_cam.getCoil_no());
			cp3.setObject(u2);
			ResultModel rm2 = this.getBean(LmsApiServiceImpl.class).doCancelIn(cp3);	
			if(rm1.getState().equals("500")){
				throw new Exception(rm2.getMsgInfo());
			}	
			// 释放虚拟母卷
			PlnMaterielDetail pmdq1=new PlnMaterielDetail();
			pmdq1.setObject_no_vt(v_rec_cam.getMaterial_no_vt());
			pmdq1.setObject_no(v_rec_cam.getMaterial_no());
			try{
				this.getBean(MesApiAnnealPlanImpl.class).AnnealFinsh_SumCancel(pmdq1);
			}catch(Exception ex){
				throw new Exception("计划接口出错！"+ ex.getMessage());
			}					
		    //--(2.9)、修改罩退作业主实绩交工状态																																							
		    this.getMapper(MesCrAnnealMMapper.class).doUpdate3(username,plp.getMachine_code(),
					plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());		    
		    
		    //2019-02-21
	  		/*
	  		检验批分批规则：
	  			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
	  			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
	  		 */
		    Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
	  		if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){
	  			List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_cam.getBatch_no()+"'", null, 0, 0);
	  			if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
  					try{
  						mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
  					}catch(Exception e){
  						
  					}
	  			}
	  		}
		    
		    //=======================质量检验委托开始=============================
		    if(v_rec_cam.getBatch_no()!=null && !"".equals(v_rec_cam.getBatch_no())){//炉批号（2位炉座号+ 2位年份 + 4位流水号）不为空
		    	try{
					QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
					String prod_order_no=v_rec_cam.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){					
						if(mc_list!=null && mc_list.size()>0){
							for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
								String key = grouplist.getKey();
								List<MesCrAnnealM> listCes = grouplist.getValue();
								for(MesCrAnnealM mcamxxx:listCes){
									String anm_key=v_rec_cam.getSteel_code()+"T"+v_rec_cam.getMtr_thk()+"T"+v_rec_cam.getMtr_wdt();
									if(anm_key.equals(key) && v_rec_cam.getMaterial_no().equals(mcamxxx.getMaterial_no())){
										ajsfp.setInspection_lot(mcamxxx.getInspection_lot());
										MesCrAnnealM mCrossleo = new MesCrAnnealM();
										//mCrossleo.setMachine_code(sum.getMemo1());
										mCrossleo.setSchedule_no(mcamxxx.getSchedule_no());
										//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
										mCrossleo.setMaterial_no(mcamxxx.getMaterial_no());
										mCrossleo.setInspection_lot(mcamxxx.getInspection_lot());
										this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									}
								}
							}
						}
						
//						ajsfp.setBatch_no(v_rec_cam.getBatch_no());//轧批号    炉次号
//						//ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
//						List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
//						if(list_plnP!=null && list_plnP.size()>0){
//							ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
//						}
//						ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
//						//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
//						//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
//						ajsfp.setHeat_no(v_rec_cam.getBatch_no());//炉号      
//						//ajsfp.setInspection_lot(v_rec_cam.getBatch_no());//检验号    炉次号
//						ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
//						ajsfp.setMaterial_no(v_rec_cam.getMaterial_no());//取样材料号   
//						ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
//						ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
//						ajsfp.setBoard_no(v_rec_cam.getMaterial_no());
//						
//						ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(mCross.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("B");//工序代码    com_base_process表
//						ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
//						//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
//						int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_cam.getMaterial_no_vt(), "B");
//						// 获取工艺路径包含成分或者材质类
//						if(judge_Contain_Qcm!=-1){
//							ajsfp.setPline_seq((long)judge_Contain_Qcm);
//							QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
//							qjsprem.setDesign_key(lpp.get(0).getDesign_key());
//							qjsprem.setInspection_lot(v_rec_cam.getInspection_lot());
//							CommonPage<QcmJhySampleFromPlan> sum22=new CommonPage<QcmJhySampleFromPlan>();
//							sum22.setObject(qjsprem);
//							this.getBean(QmsApiServiceImpl.class).removeInspection(sum22);
//						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
		    }
			//==========================质量检验委托结束==================================
		    String nextProcessCode = this.getBean(MesApiDesignInfoImpl.class).getNextProcessCode("3", v_rec_cam.getMaterial_no_vt());
			if(nextProcessCode==null || "".equals(nextProcessCode)){
				//生产订单统计 统计量并修改生产订单状态
			    try{
//			    	this.getBean(PlnProdorderStatisticServiceImpl.class).prod_Stats(v_rec_cam.getCoil_no(),1,false);
			    }catch(Exception e){
			    	System.out.println("生产订单统计 统计量并修改生产订单状态出错");
			    	e.printStackTrace();
			    }
			}
			
			
			String isOpen = this.getMapper(ComBaseInfoMapper.class).findById("9512").getMemo();
			if ("1".equals(isOpen)) {
			
				// 记录成本异动点：20230811刘侣
				YdmProductDetail ypdM = this.getMapper(YdmProductDetailMapper.class).findById(plp.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()); // 牌号
				}
				
				// 需要的字段：Coilno Width Length Prod_name Thick Orderno Steelname Factweight
				
				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("YTTH");
				cd.setLocNo("YTTH");
				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("YTTH");
				this.getBean(SlmFundFirstDetailService.class).doCbDataIns(cd, cd.getActivityId(), ypdM.getMaterailcoilno());
				// end
			}
			
			
			//日志
			MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "取消交工", username, opr_time, plp.getMaterial_no(), null, null, null, "南方退火炉");
			this.getMapper(MesOprLogMapper.class).insert(mol);	    
		}		
		r.setState("200");
		r.setMsgInfo("取消交工成功！");
		return r;
	}
	
	
	
	
	
	/***
	 * 动作处理--打印标签按钮
	* objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel printLabel(CommonPage<PlnAnnealPlan> 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);
		
		Integer v_cnt;
		try{
			if(sum.getObjectList()==null || sum.getObjectList().size()<=0){
				r.setState("500");
				r.setMsgInfo("参数错误：未指定需要取消交工的原料卷信息！");
				return r;
			}
			for(PlnAnnealPlan plp: sum.getObjectList()){
				if("".equals(plp.getAn_plan_no()) || "".equals(plp.getObject_no_vt()) || "".equals(plp.getMaterial_no())){
					r.setState("500");
					r.setMsgInfo("参数错误：作业计划号、虚拟原料卷号、原料卷号个数不匹配！");
					return r;
				}
			}
			//  --(2)、循环参数 { 作业计划号、虚拟原料卷号、原料卷号 } 集合中各元素
			for(PlnAnnealPlan plp: sum.getObjectList()){
				MesCrAnnealM mCross = new MesCrAnnealM();
				mCross.setSchedule_no(plp.getAn_plan_no());
				mCross.setMaterial_no_vt(plp.getObject_no_vt());
				mCross.setMaterial_no(plp.getMaterial_no());
				v_cnt = this.getBean(MesCrAnnealMMapper.class).count(mCross);
				if (v_cnt<=0) {
					r.setMsgInfo("原料卷号：" + plp.getMaterial_no() + "，当前不存在罩退作业实绩，请确认是否已操作上料！");
					r.setState("500");
					return r;
				}
				List<MesCrAnnealM> list_mcam = this.getBean(MesCrAnnealMMapper.class).find(mCross, 0, 0);
				if(list_mcam!=null && list_mcam.size()>0){
					if(list_mcam.get(0).getFurnace_no()==null){
						r.setMsgInfo("原料卷号：" + plp.getMaterial_no() + "，当前未指定炉座号，无法打印标签！");
						r.setState("500");
						return r;
					}
				}
			}
			//钢卷标签打印信息 SQL 如下（各钢卷逐一查询，结果一并返回到前端）：
			List<PrintLabelView> list=new ArrayList<>();
			for(PlnAnnealPlan plp: sum.getObjectList()){
				PrintLabelView plv = this.getMapper(MesCrAnnealMMapper.class).doQueryPrint(plp.getAn_plan_no(),plp.getObject_no_vt(),plp.getMaterial_no());
				list.add(plv);
				//日志
				MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "打印标签预览", username, opr_time, plv.getCoilno(), null, null, null, plv.getMachine_name());
				this.getMapper(MesOprLogMapper.class).insert(mol);
			}
			r.setState("200");
			r.setMsgInfo("打印标签成功");	
			r.setData(list);
			return r;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("打印标签失败");
		}
	}
	
	/***
	 * 动作处理--打印标签按钮
	* objectlist中：
	 * an_plan_no 作业计划号
	 * object_no_vt 虚拟卷号
	 * material_no 原料卷号
	 * @throws Exception 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel printLabelWT(CommonPage<MesCrAnnealM> 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);
		
		try{
			//钢卷标签打印信息 SQL 如下（各钢卷逐一查询，结果一并返回到前端）：
			List<PrintLabelView> list=new ArrayList<>();
			for(MesCrAnnealM plp: sum.getObjectList()){
				PrintLabelView plv = this.getMapper(MesCrAnnealMMapper.class).doQueryPrintWT(plp.getCoil_no());
				list.add(plv);
				//日志
				MesOprLog mol = new MesOprLog("车间MES", "退火炉作业管理", "打印标签预览", username, opr_time, plv.getCoilno(), null, null, null, plv.getMachine_name());
				this.getMapper(MesOprLogMapper.class).insert(mol);
			}
			r.setState("200");
			r.setMsgInfo("打印标签成功");	
			r.setData(list);
			return r;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("打印标签失败");
		}
	}
	
	/**
	 * 此功能用于提货单管理界面的打印标签，单纯打印，不判定逻辑
	 * @param sum
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel printLabel2(CommonPage<MesCrAnnealM> 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);
		try{			
			//钢卷标签打印信息 SQL 如下（各钢卷逐一查询，结果一并返回到前端）：
			List<PrintLabelView> list=new ArrayList<>();
			for(MesCrAnnealM plp: sum.getObjectList()){
				PrintLabelView plv= this.getMapper(MesCrAnnealMMapper.class).doQueryPrint2(plp.getCoil_no());
				list.add(plv);
				//日志
				MesOprLog mol = new MesOprLog("物流管理", "提货单管理", "打印标签预览", username, opr_time, plv.getCoilno(), null, null, null, plv.getMachine_name());
				this.getMapper(MesOprLogMapper.class).insert(mol);
			}
			r.setState("200");
			r.setMsgInfo("打印标签成功");	
			r.setData(list);
			return r;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("打印标签失败");
		}
	}
	
	/**
	 * object中：
	 *  钢卷号：material_no
	 *  和其他的条件，详见文档
	 * memo1:机台代码
	 * memo2:班次
	 * startTime:投料日期开始
	 * endTime:投料日期结束
	 * memo3:产出日期开始
	 * memo4:产出日期结束
	 * 动作处理_【弹窗一】查询按钮
	 * */
	public ResultModel doQueryWebM_DG(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.class).doQueryWebM_DG(oci.getObject(),oci.getStartTime(),oci.getEndTime(),oci.getMemo3(),oci.getMemo4(),oci.getMemo2(),oci.getMemo1()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**
	 * object中：
	 *  钢卷号：material_no
	 *  和其他的条件，详见文档
	 * memo1:机台代码
	 * memo2:班次
	 * startTime:投料日期开始
	 * endTime:投料日期结束
	 * memo3:产出日期开始
	 * memo4:产出日期结束
	 * 动作处理_【弹窗一】查询按钮
	 * */
	public ResultModel doQueryWebM(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.class).doQueryWebM(oci.getObject(),oci.getStartTime(),oci.getEndTime(),oci.getMemo3(),oci.getMemo4(),oci.getMemo2(),oci.getMemo1()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
		
	/**
	 * object中：
	 *  作业计划号：schedule_no
	 *  原料卷号：material_no
	 * 动作处理_【弹窗一】选择按钮
	 * */
	public ResultModel doQueryWebM2(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.class).doQueryWebM2(oci.getObject()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**
	 *  同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		检验批号编码规则：炉次号+两位流水号，示例：2619000401）
	 * @param billingList
	 * @return
	 * @throws Exception
	 */
	private Map<String, List<MesCrAnnealM>> groupBillingDataByExcpBatchCode(List<MesCrAnnealM> billingList) throws Exception{
		Map<String, List<MesCrAnnealM>> resultMap = new HashMap<String, List<MesCrAnnealM>>();
		try{
			int i=0;
			for(MesCrAnnealM tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"T"+tmExcpNew.getMtr_thk()+"T"+tmExcpNew.getMtr_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
//					i++;
//					String inspection_lot=tmExcpNew.getBatch_no()+lpad(i+"", 2, "0");
//					tmExcpNew.setInspection_lot(inspection_lot);
//					resultMap.get(key).add(tmExcpNew);
//					String inspection_lot=schedule+lpad(i+"", 2, "0");
					List<MesCrAnnealM> 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=tmExcpNew.getBatch_no()+lpad(i+"", 2, "0");
					tmExcpNew.setInspection_lot(inspection_lot);
					List<MesCrAnnealM> tmpList = new ArrayList<MesCrAnnealM>();
					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;
	}
	
	/**
	 * object中：
	 *  作业计划号：schedule_no
	 *  原料卷号：material_no
	 * 动作处理_【弹窗一】选择按钮
	 * */
	public ResultModel doQueryAnnealM(CommonPage<MesCrAnnealM> oci){
		ResultModel rm=new ResultModel();
		try{
			rm.setData(this.getMapper(MesCrAnnealMMapper.class).queryAnnealMonth(oci.getStartTime(), oci.getEndTime()));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
}
