/***文档注释***********************************************
 * 作者               :                   易鑫
 * 创建日期      :                   2017.12.06
 * 描述               :        			分条设计主表
 * 注意事项      :                   无
 * 遗留BUG :                   无
 * 修改日期      :                   
 * 修改人员      :                   
 * 修改内容      :                   
***********************************************************/

package market.Mes.Lengthwise.Design.impl;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;

import market.Api.Lms.impl.LmsApiServiceImpl;
import market.Api.Mes.impl.DesignInfo;
import market.Api.Mes.impl.MesApiDesignInfoImpl;
import market.Api.Mes.impl.MesApiServiceImpl;
import market.Api.Mes.impl.ProcessPoint;
import market.Api.Mes.impl.Utils;
import market.Api.Qms.impl.QmsApiServiceImpl;
import market.Com.mapper.ComBaseInfoMapper;
import market.Com.mapper.ComDsnCutstdMapper;
import market.Com.mapper.ComDsnPltlmtMapper;
import market.Com.vo.ComBaseInfo;
import market.Com.vo.ComDsnCutstd;
import market.Com.vo.ComDsnPltlmt;
import market.Com.vo.CommonPage;
import market.Com.vo.ResultModel;
import market.Lms.Warehouse.impl.YdmProductDetailBfServiceImpl;
import market.Lms.Warehouse.mapper.YdmProductDetailMapper;
import market.Lms.Warehouse.vo.YdmProductDetail;
import market.Mes.Lengthwise.Design.mapper.PlnDsnOrderInfoMapper;
import market.Mes.Lengthwise.Design.mapper.PlnLengthwiseDsnMainMapper;
import market.Mes.Lengthwise.Design.mapper.PlnLengthwiseDsnMultinfoMapper;
import market.Mes.Lengthwise.Design.service.PlnLengthwiseDsnMainService;
import market.Mes.Lengthwise.Design.vo.ClsRestrict;
import market.Mes.Lengthwise.Design.vo.PlnDsnOrderInfo;
import market.Mes.Lengthwise.Design.vo.PlnLengthwiseDsnMain;
import market.Mes.Lengthwise.Design.vo.PlnLengthwiseDsnMultinfo;
import market.Mes.Lengthwise.Design.vo.clsOrderDsn;
import market.Mes.Lengthwise.Design.vo.clsScheme;
import market.Mes.Lengthwise.Design.vo.clsSchemeDetail;
import market.Mes.Lengthwise.Plan.mapper.PlnMatReplaceLogMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnMaterielDetailMapper;
import market.Mes.Lengthwise.Plan.vo.PlnMatReplaceLog;
import market.Mes.Lengthwise.Plan.vo.PlnMaterielDetail;
import market.Mes.Opr.mapper.MesOprLogMapper;
import market.Mes.Opr.vo.MesOprLog;
import market.Mes.OrderManager.Plan.mapper.PlnOrderStatisticMapper;
import market.Mes.OrderManager.Plan.mapper.PlnProdorderMapper;
import market.Mes.OrderManager.Plan.mapper.PlnProdorderStatisticMapper;
import market.Mes.OrderManager.Plan.vo.PlnOrderStatistic;
import market.Mes.OrderManager.Plan.vo.PlnProdorder;
import market.Mes.OrderManager.Plan.vo.PlnProdorderStatistic;
import market.Slm.FundManagement.service.SlmFundFirstDetailService;

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

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

@RemoteService(path="PlnLengthwiseDsnMainService")
public class PlnLengthwiseDsnMainServiceImpl extends BaseServiceImpl<PlnLengthwiseDsnMain,Object> implements PlnLengthwiseDsnMainService {
	
	/**
	 * 分条挂单验证
	 * @param oci
	 * @return
	 * @throws Exception
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doOnOrderValid(CommonPage<String[]> oci) throws Exception{
		ResultModel rm=new ResultModel("200", "");
		
		//实物卷号数组
		String[] sCoilNo=oci.getObject();
		if(oci.getMemo1()==null||"".equals(oci.getMemo1().trim())||sCoilNo==null||sCoilNo.length==0){
			rm.setState("500");
			rm.setMsgInfo("条件传入错误!");
			return rm;
		}
		
		// 生产订单信息
		PlnProdorder pp=new PlnProdorder();
		pp.setProd_order_no(oci.getMemo1().trim());
		List<PlnProdorder> lpp=this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);
		if(lpp==null||lpp.size()==0){
			rm.setState("500");
			rm.setMsgInfo("生产订单["+pp.getProd_order_no()+"]不存在!");
			return rm;
		}
		for (String coilno : sCoilNo) {
			//处理逻辑
			//对传入的实物卷，查询库存信息 若不存在信息，则报错“库存中无实物[xxx]信息”
			List<YdmProductDetail> ypd = this.getMapper(YdmProductDetailMapper.class).findWithCondition(null, "coil_no = '"+coilno+"' and state = 0 ", "", 0, 1);
			if (ypd==null || ypd.size()==0) {
				rm.setState("500");
				rm.setMsgInfo("实物卷["+coilno+"]对应的库存信息不存在!");
				return rm;
			}else {
				// 客户信息不一致,返回给前端.
				if (ypd.get(0).getObject_attr() != null && "507102".equals(ypd.get(0).getObject_attr())) {
					if (ypd.get(0).getCustomer_no() != null && ypd.get(0).getCustomer_nm() != null
							&& lpp.get(0).getCustomer_no() != null && lpp.get(0).getCustomer_name() != null
							&& !ypd.get(0).getCustomer_no().equals(lpp.get(0).getCustomer_no())
							&& !ypd.get(0).getCustomer_nm().equals(lpp.get(0).getCustomer_name())) {
						rm.setState("500");
						rm.setMsgInfo("库存中,实物卷["+coilno+"]的客户信息与对应生产订单["+pp.getProd_order_no()+"]的客户信息不一致,是否强制挂单!");
						return rm;
					}
				}else {					// 挂单
					ResultModel rmValid = doRelationOrder(oci);
					if(!"200".equals(rmValid.getState())){
						throw new Exception(rmValid.getMsgInfo());
					}
				}
			}
		}
		return rm;
	}
	
	
	/**
	 * 分条挂单
	 * memo1 生产订单号
	 * memo2 1 强制充当
	 * memo3 机台代码 M0001/M0002
	 * @throws Exception 
	 * [{"memo1":"1804130000001","object":["Y1831023"]}]  挂单
	 * [{"memo1":"1804110000002","object":["Y1830550","Y1830551"]}]  挂单
	 * [{"memo1":"1804110000002","object":["Y1830550","Y1830551"],"memo2":"1"}]  强制挂单
	 * 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doRelationOrder(CommonPage<String[]> oci) throws Exception{
		ResultModel rm=new ResultModel();
	    String username = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
	    String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); //操作时间
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class)
				.findWithCondition(null, "sort_code = '2002' AND validflag = '1'",
						null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		String temp = "";
		String[] path = null;
		ArrayList<String> validpath = new ArrayList<>();
		//实物卷号数组
		String[] sCoilNo=oci.getObject();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		
		if(oci.getMemo1()==null||"".equals(oci.getMemo1().trim())||sCoilNo==null||sCoilNo.length==0){
			rm.setState("500");
			rm.setMsgInfo("条件传入错误!");
			return rm;
		}
//		if (Utils.isEmpty(oci.getMemo3())) {
//			rm.setState("500");
//			rm.setMsgInfo("请传入机台代码!");
//			return rm;
//		}
		PlnProdorder pp=new PlnProdorder();
		pp.setProd_order_no(oci.getMemo1().trim());
		List<PlnProdorder> lpp=this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);
		if(lpp==null||lpp.size()==0){
			rm.setState("500");
			rm.setMsgInfo("生产订单["+pp.getProd_order_no()+"]不存在!");
			return rm;
		}
		
		// 验证生产订单状态是否为订单保留：20230908刘侣
		if ("0PAA60".equals(lpp.get(0).getStatus())) {
			rm.setState("500");
			rm.setMsgInfo("生产订单["+lpp.get(0).getProd_order_no()+"]为 ‘订单保留’ 状态，不允许挂单");
			return rm;
		} 
		if ("0PAA70".equals(lpp.get(0).getStatus())) {
			rm.setState("500");
			rm.setMsgInfo("生产订单["+lpp.get(0).getProd_order_no()+"]为 ‘订单作废’ 状态，不允许挂单");
			return rm;
		} 
		
		// 验证生产订单是否锁定
		boolean flag_l = this.getBean(MesApiDesignInfoImpl.class).pOrdIsLocked(oci.getMemo1().trim());
		if (flag_l) {
			throw new Exception("生产订单已经锁定[订单变更中],不允许挂单!");
		}
		
		// 合同是否是厂内合同
		boolean flag_c = this.getBean(MesApiDesignInfoImpl.class).getContractType(oci.getMemo1().trim());
		
		// 合同是都是来料加工合同
		boolean flag_j = this.getBean(MesApiDesignInfoImpl.class).getCont_Type(oci.getMemo1().trim());
		
				
		//物料充当脱单履历
		List<PlnMatReplaceLog> lmmrl=this.getMapper(PlnMatReplaceLogMapper.class).findWithCondition(null, "", " serial_no desc ", 0, 1);
		long iNo=1;
		if(lmmrl!=null&&lmmrl.size()>0){
			iNo=lmmrl.get(0).getSerial_no()+1;
		}
		
		String pd="";
		if("1".equals(oci.getMemo2())){
			pd="1";
		}
		
		// 判断订单是否是净重交货 (true 不走虚拟发运,不校验第一次挂单信息)
		boolean flag = this.getBean(MesApiServiceImpl.class).judgeOrderWeightType(oci.getMemo1());
		if(!"1".equals(lpp.get(0).getOrder_nature()) && !"3".equals(lpp.get(0).getOrder_nature())){
			//处理逻辑1
			if("0PAA12".compareTo(lpp.get(0).getStatus())>0){
				rm.setState("500");
				rm.setMsgInfo("[需加工]的订单，要下发生产后才能挂单！");
				return rm;
			}
			
			for(String CoilNo:sCoilNo){
				List<DesignInfo> infos = new ArrayList<>();
				//处理逻辑
				//对传入的实物卷，查询库存信息[物流接口]
				//存在信息，则读取之； 若不存在信息，则报错“库存中无实物[xxx]信息”
				CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
				YdmProductDetail ypd=new YdmProductDetail();
				ypd.setCoilno(CoilNo);
				cp.setObject(ypd);
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doFindCoilno(cp);
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
				
				// 挂单后判断该卷是否已经iscanload：是 就置为null，让其重新判断iscanload；20230210刘侣
				YdmProductDetail ypdCanLoad = new YdmProductDetail();
				ypdCanLoad.setCoilno(CoilNo);
				ypdCanLoad.setIs_can_load("1");
				List<YdmProductDetail> ypdCanList = this.getMapper(YdmProductDetailMapper.class).find(ypdCanLoad, 0, 0);
				if (ypdCanList != null && ypdCanList.size() > 0) {
					ypdCanList.get(0).setIs_can_load("0");
					this.getMapper(YdmProductDetailMapper.class).update(ypdCanList.get(0));
					this.getMapper(YdmProductDetailMapper.class).kctbYdd(ypdCanList.get(0).getCoilno());
				}
				// end
				
				// 2018-06-15 限制重复挂单加此操作
				@SuppressWarnings("unchecked")
				List<YdmProductDetail> lypd = (List<YdmProductDetail>) rmValid.getData();
				for (YdmProductDetail ydmp : lypd) {
					if (ydmp.getOrderno() != null) {
						rm.setState("500");
						rm.setMsgInfo("实物["+cp.getObject().getCoilno()+"]已绑定订单["+ydmp.getOrderno()+"]! 不能再次操作!");
						return rm;
					}else if(!flag_c && !flag_j){
						PlnMaterielDetail pmd = new PlnMaterielDetail();
						pmd.setObject_no(ydmp.getCoilno());
						List<PlnMaterielDetail> pmdd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(pmd, "nvl(invalid_flg,0) = 0", "", 0, 0);
						if (pmdd != null && pmdd.size()>0) {
							for (PlnMaterielDetail plnmaterieldetail : pmdd) {
								plnmaterieldetail.setObject_no("");
								this.getMapper(PlnMaterielDetailMapper.class).update(plnmaterieldetail);
							}
						}
					}
					if (!"1".equals(pd)) {
						// 如果物料是成品校验综合判定信息
						/*if ("500203".equals(ydmp.getStorageattr()) && !"1".equals(ydmp.getIsbl()) &&  !"40740801".equals(ydmp.getJudgeresult())){
							throw new Exception("成品挂单之前需要综合判定合格!");
						}*/
//						19-10-16改
						if ("500203".equals(ydmp.getStorageattr()) && !"1".equals(ydmp.getIsbl()) &&ydmp.getJudgeresult()==null){
							throw new Exception("成品挂单之前需要综合判定!");
						}
					}
				}
				if(!lpp.get(0).getSteel_code().equals(lypd.get(0).getJudgesteelcode())){
					throw new Exception("牌号不匹配，不能上料！");
				}
				
				if (!"1".equals(pd)) {
					// 拆分订单不验证合同号
					if (!(lpp.get(0).getIs_split() != null && "1".equals(lpp.get(0).getIs_split()))) {
						if (!flag && !flag_c && !flag_j) {
							// 判断第一次挂单与第二次挂单合同号contract_no是否一致 2018-09-05 通过挂单日志表获取最后一条脱单的订单信息(原料卷订单 属性为新钢
							// 最后一个)
							List<PlnProdorder> plnlog = this.getMapper(PlnMatReplaceLogMapper.class).findreplacelog(CoilNo);
							if (Utils.isNotEmpty(plnlog)) {
								if (!lpp.get(0).getContract_no().equals(plnlog.get(0).getContract_no())) {
									// 去掉这个限制lanyushan：20231113刘侣
//									throw new Exception("合同号不匹配，不能上料! 合同号 : [" + plnlog.get(0).getContract_no() + ","
//											+ lpp.get(0).getContract_no() + "]");
								}
							} else {
								// 暂时先注释掉：20230107刘侣
								// 黄涛操作和蓝雨珊不一样，所以先把这个注释掉：黄涛需求 2023011301
//								throw new Exception("未找到[" + CoilNo + "]对应原料卷订单挂单信息!");
							}
						}
					}
					if (lpp.get(0).getThick() == null) {
						throw new Exception("未找到生产订单厚度，不能上料！");
					}
					if (lypd.get(0).getThick() == null) {
						throw new Exception("未找到实物厚度，不能上料！");
					}
					
					ResultModel rmInfo = this.getBean(MesApiServiceImpl.class)
							.CompareValues(lpp.get(0).getThick().doubleValue(),
									lypd.get(0).getThick().doubleValue());
					if (!"200".equals(rmInfo.getState())) {
						throw new Exception(rmInfo.getMsgInfo());
					}

					// 判断实物，和订单原料卷的宽，如果实物比订单值小，则报错退出
					if (lypd.get(0).getWidth().doubleValue() < lpp.get(0)
							.getWidth().doubleValue()) {
						throw new Exception("实物卷的宽比订单要求值小，不能上料！");
					}
					
					// 判断客户信息是否一致-----------------2018-07-04-----------------------------
					if (!flag && lypd.get(0).getCustomer_no() != null
							&& lpp.get(0).getCustomer_no() != null
							&& !lypd.get(0).getCustomer_no()
									.equals(lpp.get(0).getCustomer_no())) {
						throw new Exception(
								"库存中实物卷的客户信息与对应生产订单的客户信息不一致! 可选强制挂单! \r\n "
										+ "卷号:[" + CoilNo + "] 客户名称:["
										+ lypd.get(0).getCustomer_nm()
										+ "] \r\n " + "生产订单号 :["
										+ pp.getProd_order_no() + "] 客户名称 :["
										+ lpp.get(0).getCustomer_name() + "]");
					}

					// 读取基础配置 产线机组限制表,根据厚度信息读取允许的最大分条数
//					List<ComDsnPltlmt> lc = this.getBean(
//							MesApiServiceImpl.class).getMachineRestrictDb(
//							lpp.get(0).getThick(), oci.getMemo3());
//					ClsRestrict MachineRestrict = new ClsRestrict(lc);
					// 根据传入的生产订单号，读取生产订单对应的生产加工表[PLN_PROCESS_PLAN]
//					PlnProcessPlan pppc = new PlnProcessPlan();
//					pppc.setOrder_no(lpp.get(0).getOrder_no());
//					pppc.setValid_flag("1");
//					List<PlnProcessPlan> lppp = this.getMapper(
//							PlnProcessPlanMapper.class).findWithCondition(pppc,
//							null, " cut_order_no ", 0, 0);
//					if (lppp == null || lppp.size() == 0) {
//						throw new Exception("未找到生产订单[" + pppc.getOrder_no()
//								+ "]对应的生产加工信息");
//					}

//					ResultModel thick_rm = this.getBean(
//							PbModelDbServiceImpl.class)
//							.findPlnThickRangeCmbDb();
//					if (!"200".equals(thick_rm.getState())){
//						throw new Exception("获取厚度公差范围失败！");
//					}
//					List<PbModelDb> lpmdd = (List<PbModelDb>) thick_rm
//							.getData();
//					if (lpmdd == null || lpmdd.size() == 0) {
//						throw new Exception("请先配置厚度公差范围！");
//					}

					// --------------获取配置的值比较公差范围------------------
//					for (PbModelDb pmd : lpmdd) {
//						if (pmd.getId().equals("200101")) {// 范围
//							if (lypd.get(0).getThick().doubleValue()
//									- MachineRestrict.lim_max_height > (Double
//										.parseDouble(pmd.getRegionkey()))) {
//								throw new Exception("母卷[" + ypd.getCoilno()
//										+ "]的厚度超出最大公差设备限制范围内，不能分条！");
//							}
//						}
//
//						if (pmd.getId().equals("200102")) {
//							if (lypd.get(0).getThick().doubleValue()
//									- MachineRestrict.lim_min_height < (Double
//										.parseDouble(pmd.getRegionkey()))) {
//								throw new Exception("母卷[" + ypd.getCoilno()
//										+ "]的厚度小于最小公差设备限制范围内，不能分条！");
//							}
//						}
//						// --------------------------------
//
//						if (lypd.get(0).getWidth().doubleValue() > MachineRestrict.lim_max_wdt
//								|| lypd.get(0).getWidth().doubleValue() < MachineRestrict.lim_min_wdt) {
//							throw new Exception("母卷[" + lypd.get(0).getCoilno()
//									+ "]的宽度不在设备限制范围内，不能挂单！");
//						}
//						if (lypd.get(0).getFactweight().doubleValue() > MachineRestrict.lim_max_wgt) {
//							throw new Exception("母卷[" + lypd.get(0).getCoilno()
//									+ "]的重量不在设备限制范围内，不能挂单！");
//						}
//						// 对于母卷S1的 其他规格信息(内径、外径)， 如果无值，则继续；
//						// 如果有值，则判断是否在设备原料的限制范围内
//						if (lypd.get(0).getDiameter_inn() != null
//								&& lypd.get(0).getDiameter_inn().intValue() != 0) {
//							if (lypd.get(0).getDiameter_inn().doubleValue() > MachineRestrict.lim_max_inner
//									|| lypd.get(0).getDiameter_inn().doubleValue() < MachineRestrict.lim_min_inner) {
//								throw new Exception("母卷[" + lypd.get(0).getCoilno()
//										+ "]的内径不在设备限制范围内，不能挂单！");
//							}
//						}
//						if (lypd.get(0).getDiameter_out() != null
//								&& lypd.get(0).getDiameter_out().intValue() != 0) {
//							if (lypd.get(0).getDiameter_out().doubleValue() > MachineRestrict.lim_max_outter
//									|| lypd.get(0).getDiameter_out().doubleValue() < MachineRestrict.lim_min_outter) {
//								throw new Exception("母卷[" + lypd.get(0).getCoilno()
//										+ "]的外径不在设备限制范围内，不能挂单！");
//							}
//						}
//					}
//					double sWidth = 0;
					// 判断成品宽度之和与原料卷宽的差>0 or < 1报错
//					for (PlnProcessPlan pb : lppp) {
//						sWidth += pb.getCut_num() * pb.getWidth();
//					}
//					if (sWidth + 1 < lypd.get(0).getWidth().doubleValue()   || sWidth > lypd.get(0).getWidth().doubleValue()) {
//						throw new Exception("成品规格之和,超过了原料卷允许范围,不能挂单!");
//					}
				}
				// 生成设计信息
				if (Utils.isNotEmpty(lpp.get(0).getWhole_process_codes()) && !"1".equals(lpp.get(0).getWhole_coil())) {
					// 1、获取有效工艺路径
					temp = processpoint.slitting_code + StringUtils.substringAfter(lpp.get(0).getWhole_process_codes(), processpoint.slitting_code);
					path = temp.split("-");
					validpath = this.getBean(MesApiDesignInfoImpl.class).getProcessPath(path);
					// 调用设计信息接口
					DesignInfo info = new DesignInfo();
					// 如果实物对应的虚拟物料信息存在,即传入虚拟物料号(厂内合同成品再加工)
					List<PlnMaterielDetail> pmd_c = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no = '"+CoilNo+"' and nvl(invalid_flg,0) = 0", "", 0, 0);
					if (Utils.isNotEmpty(pmd_c)) {
						info.setObject_no_vt(pmd_c.get(0).getObject_no_vt());
					}
					info.setCurrentProcIndex(0);
					info.setObject_no(CoilNo);
					info.setProcess(validpath);
					info.setProd_order_no(oci.getMemo1());
					info.setSingle_wgt(lypd.get(0).getFactweight());
					infos.add(info);
					ResultModel result = this.getBean(MesApiDesignInfoImpl.class).Design_Plan_Info(infos,null);
					if (!"200".equals(result.getState())) {
						throw new Exception("生产设计信息失败" + result.getMsgInfo());
					}
				}
				
				
				//**************调用质量接口，传入 订单号和实物卷号，判断其他要求是否符合，不符合则报错退出**********
//				PlnLengthwiseDsnMain pld=this.getBean(MesApiServiceImpl.class).ProcessingPlanDsn(lpp.get(0).getProd_order_no(), 1, lypd.get(0),pd,oci.getMemo3());
				
				// 反写母卷虚拟物料机台产线
//				PlnMaterielDetail pmdM=new PlnMaterielDetail();
//				pmdM.setObject_no(CoilNo);
//				if ("M0001".equals(oci.getMemo3())) {
//					pmdM.setPline_code("C001");
//				}else {
//					pmdM.setPline_code("C002");
//				}
//				pmdM.setMachine_code(oci.getMemo3()); // 挂单的时候确认机台产线
//				this.getMapper(PlnMaterielDetailMapper.class).updateMachine_Code(pmdM);
				
				// 整卷发运
				if ("1".equals(lpp.get(0).getWhole_coil())) {
					
					//保存相关数据
					//修改生产订单进程表[PLN_PRODORDER_STATISTIC]
					PlnProdorderStatistic pps=new PlnProdorderStatistic();
					pps.setProd_order_no(lpp.get(0).getProd_order_no());
					pps.setReplaced(lypd.get(0).getFactweight());
					pps.setReplaced_cnt(1);
					pps.setReplaced_times(1);
					pps.setUnscheduled(lypd.get(0).getFactweight()==null?null:(-lypd.get(0).getFactweight()));
					this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
					
					
					//修改订单进程表[PLN_ORDER_STATISTIC]
					PlnOrderStatistic pos=new PlnOrderStatistic();
					pos.setOrder_no(lpp.get(0).getOrder_no());
					pos.setReplaced(lypd.get(0).getFactweight());
					pos.setReplaced_cnt(1);
					pos.setReplaced_times(1);
					pos.setUnscheduled(lypd.get(0).getFactweight()==null?null:(-lypd.get(0).getFactweight()));
					this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
					
					//调用物流接口，关联实物和生产订单信息
					ypd.setProdorderno(lpp.get(0).getProd_order_no());
					ypd.setOrderno(lpp.get(0).getOrder_no());
					ypd.setCustomer_no(lpp.get(0).getCustomer_no());
					ypd.setCustomer_nm(lpp.get(0).getCustomer_name());
					ypd.setReceiv_nm(lpp.get(0).getReciver_unit_name());
					ypd.setReceiv_no(lpp.get(0).getReciver_unit_no());
					ypd.setDelivery_state_code(lpp.get(0).getDelivery_state_code());
					ypd.setDelivery_state_desc(lpp.get(0).getDelivery_state_desc());
					this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(ypd);
					
					
					//写物料充当脱单履历表[MIL_MAT_REPLACE_LOG]  MilMatReplaceLog
					PlnMatReplaceLog mmrl=new PlnMatReplaceLog();
					mmrl.setSerial_no(iNo++);
					mmrl.setObject_no(lypd.get(0).getCoilno());
					mmrl.setOpt_type("2");
					mmrl.setOrder_no(lpp.get(0).getOrder_no());
					mmrl.setProd_order_no(lpp.get(0).getProd_order_no());
					mmrl.setCreate_man_name(userName);
					mmrl.setCreate_time(new Date());
					mmrl.setRemark("整卷发运");
					this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
				}else {
					
					// 修改生产订单进程表[PLN_PRODORDER_STATISTIC] 订单进程表
					this.getBean(MesApiDesignInfoImpl.class).updateOrderStatic(lpp.get(0).getProd_order_no(), lpp.get(0).getOrder_no(), lpp.get(0).getWhole_process_codes(), lypd.get(0).getFactweight(),true);
					
					List<PlnMaterielDetail> pmdetail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, " object_no = '"+CoilNo+"' and nvl(invalid_flg,0)=0", null, 0, 1);
					
					//调用物流接口，关联实物和生产订单信息
					ypd.setCustomer_no(lpp.get(0).getCustomer_no());
					ypd.setCustomer_nm(lpp.get(0).getCustomer_name());
					ypd.setReceiv_nm(lpp.get(0).getReciver_unit_name());
					ypd.setReceiv_no(lpp.get(0).getReciver_unit_no());
					ypd.setProdorderno(lpp.get(0).getProd_order_no());
					ypd.setOrderno(lpp.get(0).getOrder_no());
					ypd.setObject_no_vt(pmdetail.get(0).getObject_no_vt());
					ypd.setDelivery_state_code(lpp.get(0).getDelivery_state_code());
					ypd.setDelivery_state_desc(lpp.get(0).getDelivery_state_desc());
					this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(ypd);
					
					
					//写物料充当脱单履历表[MIL_MAT_REPLACE_LOG]  MilMatReplaceLog
					PlnMatReplaceLog mmrl=new PlnMatReplaceLog();
					BeanUtils.copyProperties(pmdetail.get(0), mmrl);
					mmrl.setSerial_no(iNo++);
					mmrl.setOpt_type("2");
					mmrl.setProcess(processpoint.slitting_code);
					mmrl.setCreate_man_name(userName);
					mmrl.setCreate_time(new Date());
					mmrl.setRemark("1".equals(pd)?"强制充当":"");
					this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
					
					// 生成物料附加信息
					this.getBean(MesApiDesignInfoImpl.class).addMaterielExinfo(lpp.get(0), pmdetail.get(0), processpoint.slitting_code);
					
					// 拆分订单如果还需继续生产,判断是否需要移动库存 2019-08-05
					if ((lpp.get(0).getIs_split() != null && "1".equals(lpp.get(0).getIs_split()))) {
						// 如果物料在成品库挪到在制库
						if ("500203".equals(lypd.get(0).getStorageattr())) {
	//						ypd.setStorageattr("500203");
							CommonPage<YdmProductDetail> tmp = new CommonPage<YdmProductDetail>();
							List<YdmProductDetail> ydm = new ArrayList<YdmProductDetail>();
							lypd.get(0).setMemo("拆分订单["+lpp.get(0).getOrder_no()+"]增加["+lpp.get(0).getWhole_process_names()+"]工序->移至在制库");
							ydm.add(lypd.get(0));
							tmp.setObjectList(ydm);
							tmp.setMemo1("500202");
							tmp.setMemo2("0");
							this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(tmp);
						}
					}
				}
				
				ResultModel rejRes = this.getBean(SlmFundFirstDetailService.class).reAutoUltiJudge(CoilNo);
				if (!"200".equals(rejRes.getState())) {
					throw new Exception(rejRes.getMsgInfo());
				}
				
				this.getBean(SlmFundFirstDetailService.class).ycjsPYdd(CoilNo, true); // 一次结算后抛异动点
			}
		}else{
//			//处理逻辑2
//			if("0PAA12".compareTo(lpp.get(0).getStatus())<=0){
//				rm.setState("500");
//				rm.setMsgInfo("[原料卷/非计划]的订单，必须在下发生产前充当！");
//				return rm;
//			}
			
			
			for(String CoilNo:sCoilNo){
				//处理逻辑
				//对传入的实物卷，查询库存信息[物流接口]
				//存在信息，则读取之； 若不存在信息，则报错“库存中无实物[xxx]信息”
				CommonPage<YdmProductDetail> cp=new CommonPage<YdmProductDetail>();
				YdmProductDetail ypd=new YdmProductDetail();
				ypd.setCoilno(CoilNo);
				cp.setObject(ypd);
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doFindCoilno(cp);
				if(!"200".equals(rmValid.getState())){
					throw new Exception(rmValid.getMsgInfo());
				}
				
				// 挂单后判断该卷是否已经iscanload：是 就置为null，让其重新判断iscanload；20230210刘侣
				YdmProductDetail ypdCanLoad = new YdmProductDetail();
				ypdCanLoad.setCoilno(CoilNo);
				ypdCanLoad.setIs_can_load("1");
				List<YdmProductDetail> ypdCanList = this.getMapper(YdmProductDetailMapper.class).find(ypdCanLoad, 0, 0);
				if (ypdCanList != null && ypdCanList.size() > 0) {
					ypdCanList.get(0).setIs_can_load("0");
					this.getMapper(YdmProductDetailMapper.class).update(ypdCanList.get(0));
					this.getMapper(YdmProductDetailMapper.class).kctbYdd(ypdCanList.get(0).getCoilno());
				}
				// end
				
				// 2018-06-15 限制重复挂单加此操作
				@SuppressWarnings("unchecked")
				List<YdmProductDetail> lypd = (List<YdmProductDetail>) rmValid.getData();
				for (YdmProductDetail ydmp : lypd) {
					if (ydmp.getOrderno() != null) {
						rm.setState("500");
						rm.setMsgInfo("实物["+cp.getObject().getCoilno()+"]已绑定订单["+ydmp.getOrderno()+"]! 不能再次操作!");
					}else if(!flag_c && !flag_j){
						PlnMaterielDetail pmd = new PlnMaterielDetail();
						pmd.setObject_no(ydmp.getCoilno());
						List<PlnMaterielDetail> pmdd = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(pmd, "nvl(invalid_flg,0) = 0", "", 0, 0);
						if (pmdd != null && pmdd.size()>0) {
							for (PlnMaterielDetail plnmaterieldetail : pmdd) {
								plnmaterieldetail.setObject_no("");
								this.getMapper(PlnMaterielDetailMapper.class).update(plnmaterieldetail);
							}
						}
					}
				}
			
				//判断实物，和订单原料卷的厚、牌号、交货状态是否匹配
//				List<YdmProductDetail> lypd=(List<YdmProductDetail>)rmValid.getData();
				if(lpp.get(0).getSteel_code()!=null&&
						!lpp.get(0).getSteel_code().equals(lypd.get(0).getJudgesteelcode())){
					throw new Exception("牌号不匹配，不能上料！");
				}
			
				if(!"1".equals(pd)){
					/*if(lpp.get(0).getThick()!=null&&
							!lpp.get(0).getThick().equals(lypd.get(0).getThick())){
						throw new Exception("厚度不匹配，不能上料！");
					}*/
					if(lpp.get(0).getThick()!=null){
						ResultModel rmInfo=this.getBean(MesApiServiceImpl.class).CompareValues(lpp.get(0).getThick().doubleValue(), lypd.get(0).getThick().doubleValue());
						if(!"200".equals(rmInfo.getState())){
							throw new Exception(rmInfo.getMsgInfo());
						}
					}
					
					
					//判断实物，和订单原料卷的宽、重量信息，如果实物比订单值小，则报错退出
					if(lpp.get(0).getWidth()!=null&&
							lypd.get(0).getWidth().doubleValue()<lpp.get(0).getWidth().doubleValue()){
						throw new Exception("实物卷的宽比订单要求值小，不能上料！");
					}
					
					if(lpp.get(0).getSingle_weight_max()!=null&&
							lpp.get(0).getSingle_weight_max()!=null){
						if(lypd.get(0).getFactweight().doubleValue() >lpp.get(0).getSingle_weight_max().doubleValue()){
							throw new Exception("实物卷的重量比订单要求重量上限大，不能上料！");
						}
					}
					if(lpp.get(0).getSingle_weight_min()!=null&&
							lpp.get(0).getSingle_weight_min()!=null){
						if(lypd.get(0).getFactweight().doubleValue() <lpp.get(0).getSingle_weight_min().doubleValue()){
							throw new Exception("实物卷的重量比订单要求重量下限小，不能上料！");
						}
					}
					
					// 判断客户信息是否一致-----------------2018-07-04-----------------------------
//					if (lypd.get(0).getObject_attr() != null && "507102".equals(lypd.get(0).getObject_attr())) {
//						if (lypd.get(0).getCustomer_no() != null && lpp.get(0).getCustomer_no() != null
//								&& !lypd.get(0).getCustomer_no().equals(lpp.get(0).getCustomer_no())) {
//							throw new Exception("库存中实物卷的客户信息与对应生产订单的客户信息不一致! 可选强制挂单! \r\n"
//											+ "卷号:["+CoilNo+"] 客户名称:["+lypd.get(0).getCustomer_nm()+"] \r\n"
//											+ "生产订单号 :["+pp.getProd_order_no()+"] 客户名称 :["+ lpp.get(0).getCustomer_name()+"]");
//						}
//					}
				}
				
				//保存相关数据
				//修改生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps=new PlnProdorderStatistic();
				pps.setProd_order_no(lpp.get(0).getProd_order_no());
				pps.setReplaced(lypd.get(0).getFactweight());
				pps.setReplaced_cnt(1);
				pps.setReplaced_times(1);
				pps.setUnscheduled(lypd.get(0).getFactweight()==null?null:(-lypd.get(0).getFactweight()));
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
				
				
				//修改订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic pos=new PlnOrderStatistic();
				pos.setOrder_no(lpp.get(0).getOrder_no());
				pos.setReplaced(lypd.get(0).getFactweight());
				pos.setReplaced_cnt(1);
				pos.setReplaced_times(1);
				pos.setUnscheduled(lypd.get(0).getFactweight()==null?null:(-lypd.get(0).getFactweight()));
				this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
				
				
				//调用物流接口，关联实物和生产订单信息
				ypd.setProdorderno(pps.getProd_order_no());
				ypd.setOrderno(pos.getOrder_no());
				ypd.setCustomer_no(lpp.get(0).getCustomer_no());
				ypd.setCustomer_nm(lpp.get(0).getCustomer_name());
				ypd.setReceiv_nm(lpp.get(0).getReciver_unit_name());
				ypd.setReceiv_no(lpp.get(0).getReciver_unit_no());
				ypd.setDelivery_state_code(lpp.get(0).getDelivery_state_code());
				ypd.setDelivery_state_desc(lpp.get(0).getDelivery_state_desc());
				this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(ypd);
				
				
				//写物料充当脱单履历表[MIL_MAT_REPLACE_LOG]  MilMatReplaceLog
				PlnMatReplaceLog mmrl=new PlnMatReplaceLog();
				mmrl.setSerial_no(iNo++);
				mmrl.setObject_no(lypd.get(0).getCoilno());
				mmrl.setOpt_type("1");
				mmrl.setOrder_no(pos.getOrder_no());
				mmrl.setProd_order_no(pps.getProd_order_no());
				mmrl.setCreate_man_name(userName);
				mmrl.setCreate_time(new Date());
				mmrl.setRemark("1".equals(pd)?"强制充当":"");
				this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
				
				ResultModel rejRes = this.getBean(SlmFundFirstDetailService.class).reAutoUltiJudge(CoilNo);
				if (!"200".equals(rejRes.getState())) {
					throw new Exception(rejRes.getMsgInfo());
				}
				
				this.getBean(SlmFundFirstDetailService.class).ycjsPYdd(CoilNo, true); // 一次结算后抛异动点
			}
		}
		//日志
		MesOprLog mol = new MesOprLog("生产管理", "小纵剪挂单管理", "挂单", username, opr_time, null, null, null, null, Arrays.toString(sCoilNo));
		this.getMapper(MesOprLogMapper.class).insert(mol);
		rm.setState("200");
		return rm;
	}
	
	
	/**
	 * 分条强制挂单不验证牌号 memo1 生产订单号
	 * 
	 * @throws Exception [{"memo1":"1804130000001","object":["Y1831023"]}] 挂单
	 *                   [{"memo1":"1804110000002","object":["Y1830550","Y1830551"]}]
	 *                   [{"memo1":"1804110000002","object":["Y1830550","Y1830551"],"memo2":"1"}]
	 *                   强制挂单 只提供给黄涛使用
	 * 
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doRelationOrderNoValidingSteel(CommonPage<String[]> oci) throws Exception {
		ResultModel rm = new ResultModel();
		String username = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		String opr_time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); //操作时间
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class).findWithCondition(null,
				"sort_code = '2002' AND validflag = '1'", null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		
		// 验证生产订单是否锁定
		boolean flag_l = this.getBean(MesApiDesignInfoImpl.class).pOrdIsLocked(oci.getMemo1().trim());
		if (flag_l) {
			throw new Exception("生产订单已经锁定[订单变更中],不允许挂单!");
		}
				
		String temp = "";
		String[] path = null;
		ArrayList<String> validpath = new ArrayList<>();
		List<DesignInfo> infos = new ArrayList<>();
		// 实物卷号数组
		String[] sCoilNo = oci.getObject();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		
//		if (!"黄涛".equals(userName) && !"管理员".equals(userName)) {
//			rm.setState("500"); 
//			rm.setMsgInfo("您无此功能操作权限!");
//			return rm;
//		}

		if (oci.getMemo1() == null || "".equals(oci.getMemo1().trim()) || sCoilNo == null || sCoilNo.length == 0) {
			rm.setState("500");
			rm.setMsgInfo("条件传入错误!");
			return rm;
		}
		PlnProdorder pp = new PlnProdorder();
		pp.setProd_order_no(oci.getMemo1().trim());
		List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).find(pp, 0, 1);
		if (lpp == null || lpp.size() == 0) {
			rm.setState("500");
			rm.setMsgInfo("生产订单[" + pp.getProd_order_no() + "]不存在!");
			return rm;
		}
		
		if ("0PAA60".equals(lpp.get(0).getStatus())) {
			rm.setState("500");
			rm.setMsgInfo("生产订单["+lpp.get(0).getProd_order_no()+"]为 ‘订单保留’ 状态，不允许挂单");
			return rm;
		}
		if ("0PAA70".equals(lpp.get(0).getStatus())) {
			rm.setState("500");
			rm.setMsgInfo("生产订单["+lpp.get(0).getProd_order_no()+"]为 ‘订单作废’ 状态，不允许挂单");
			return rm;
		}

		
		// 合同是否是厂内合同
		boolean flag_c = this.getBean(MesApiDesignInfoImpl.class).getContractType(oci.getMemo1().trim());
		
		// 合同是都是来料加工合同
		boolean flag_j = this.getBean(MesApiDesignInfoImpl.class).getCont_Type(oci.getMemo1().trim());
				
		// 物料充当脱单履历
		List<PlnMatReplaceLog> lmmrl = this.getMapper(PlnMatReplaceLogMapper.class).findWithCondition(null, "",
				" serial_no desc ", 0, 1);
		long iNo = 1;
		if (lmmrl != null && lmmrl.size() > 0) {
			iNo = lmmrl.get(0).getSerial_no() + 1;
		}

		// 判断订单是否是净重交货 (true 不走虚拟发运,不校验第一次挂单信息)
		boolean flag = this.getBean(MesApiServiceImpl.class).judgeOrderWeightType(oci.getMemo1());
		if (!"1".equals(lpp.get(0).getOrder_nature()) && !"3".equals(lpp.get(0).getOrder_nature())) {
			// 处理逻辑1
			if ("0PAA12".compareTo(lpp.get(0).getStatus()) > 0) {
				rm.setState("500");
				rm.setMsgInfo("[需加工]的订单，要下发生产后才能挂单！");
				return rm;
			}

			for (String CoilNo : sCoilNo) {
				// 处理逻辑
				// 对传入的实物卷，查询库存信息[物流接口]
				// 存在信息，则读取之； 若不存在信息，则报错“库存中无实物[xxx]信息”
				CommonPage<YdmProductDetail> cp = new CommonPage<YdmProductDetail>();
				YdmProductDetail ypd = new YdmProductDetail();
				ypd.setCoilno(CoilNo);
				cp.setObject(ypd);
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doFindCoilno(cp);
				if (!"200".equals(rmValid.getState())) {
					throw new Exception(rmValid.getMsgInfo());
				}
				
				// 挂单后判断该卷是否已经iscanload：是 就置为null，让其重新判断iscanload；20230210刘侣
				YdmProductDetail ypdCanLoad = new YdmProductDetail();
				ypdCanLoad.setCoilno(CoilNo);
				ypdCanLoad.setIs_can_load("1");
				List<YdmProductDetail> ypdCanList = this.getMapper(YdmProductDetailMapper.class).find(ypdCanLoad, 0, 0);
				if (ypdCanList != null && ypdCanList.size() > 0) {
					ypdCanList.get(0).setIs_can_load("0");
					this.getMapper(YdmProductDetailMapper.class).update(ypdCanList.get(0));
					this.getMapper(YdmProductDetailMapper.class).kctbYdd(ypdCanList.get(0).getCoilno());
				}
				// end
				
				// 2018-06-15 限制重复挂单加此操作
				@SuppressWarnings("unchecked")
				List<YdmProductDetail> lypd = (List<YdmProductDetail>) rmValid.getData();
				for (YdmProductDetail ydmp : lypd) {
					if (ydmp.getOrderno() != null) {
						rm.setState("500");
						rm.setMsgInfo(
								"实物[" + cp.getObject().getCoilno() + "]已绑定订单[" + ydmp.getOrderno() + "]! 不能再次操作!");
						return rm;
					} else if(!flag_c && !flag_j){
						PlnMaterielDetail pmd = new PlnMaterielDetail();
						pmd.setObject_no(ydmp.getCoilno());
						List<PlnMaterielDetail> pmdd = this.getMapper(PlnMaterielDetailMapper.class)
								.findWithCondition(pmd, "nvl(invalid_flg,0) = 0", "", 0, 0);
						if (pmdd != null && pmdd.size() > 0) {
							for (PlnMaterielDetail plnmaterieldetail : pmdd) {
								plnmaterieldetail.setObject_no("");
								this.getMapper(PlnMaterielDetailMapper.class).update(plnmaterieldetail);
							}
						}
					}
				}
				
				// 拆分订单不验证合同号
				if (!(lpp.get(0).getIs_split() != null && "1".equals(lpp.get(0).getIs_split()))) {
					if (!flag && !flag_c && !flag_j) {
						// 判断第一次挂单与第二次挂单合同号contract_no是否一致 2018-09-05 通过挂单日志表获取最后一条脱单的订单信息(原料卷订单 属性为新钢
						// 最后一个)
						List<PlnProdorder> plnlog = this.getMapper(PlnMatReplaceLogMapper.class).findreplacelog(CoilNo);
						if (Utils.isNotEmpty(plnlog)) {
							if (!lpp.get(0).getContract_no().equals(plnlog.get(0).getContract_no())) {
								// 去掉这个限制lanyushan：20231113刘侣
//								throw new Exception("合同号不匹配，不能上料! 合同号 : [" + plnlog.get(0).getContract_no() + ","
//										+ lpp.get(0).getContract_no() + "]");
							}
						} else {
							// 暂时先注释掉：20230107刘侣
							// 黄涛操作和蓝雨珊不一样，所以先把这个注释掉：黄涛需求 2023011301
//							throw new Exception("未找到[" + CoilNo + "]对应原料卷订单挂单信息!");
						}
					}
				}
				// 生成设计信息
				if (Utils.isNotEmpty(lpp.get(0).getWhole_process_codes()) && !"1".equals(lpp.get(0).getWhole_coil())) {
					// 1、获取有效工艺路径
					temp = processpoint.slitting_code + StringUtils.substringAfter(lpp.get(0).getWhole_process_codes(),
							processpoint.slitting_code);
					path = temp.split("-");
					validpath = this.getBean(MesApiDesignInfoImpl.class).getProcessPath(path);
					// 调用设计信息接口
					DesignInfo info = new DesignInfo();
					// 如果实物对应的虚拟物料信息存在,即传入虚拟物料号(厂内合同成品再加工)
					List<PlnMaterielDetail> pmd_c = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "object_no = '"+CoilNo+"' and nvl(invalid_flg,0) = 0", "", 0, 0);
					if (Utils.isNotEmpty(pmd_c)) {
						info.setObject_no_vt(pmd_c.get(0).getObject_no_vt());
					}
					info.setCurrentProcIndex(0);
					info.setObject_no(CoilNo);
					info.setProcess(validpath);
					info.setProd_order_no(oci.getMemo1());
					info.setSingle_wgt(lypd.get(0).getFactweight());
					infos.add(info);
					ResultModel result = this.getBean(MesApiDesignInfoImpl.class).Design_Plan_Info(infos, null);
					if (!"200".equals(result.getState())) {
						throw new Exception("生产设计信息失败" + result.getMsgInfo());
					}
				}

				// 如果牌号不匹配
				if (!lpp.get(0).getSteel_code().equals(lypd.get(0).getJudgesteelcode()) || !lpp.get(0).getSteel_code().equals(lypd.get(0).getSteelcode())) {
					// 1、备份库存信息
					CommonPage<YdmProductDetail> sum = new CommonPage<YdmProductDetail>();
					YdmProductDetail detail = new YdmProductDetail();
					detail.setCoilno(CoilNo);
					List<YdmProductDetail> ydmlist = new ArrayList<YdmProductDetail>();
					ydmlist.add(detail);
					sum.setObjectList(ydmlist);
					this.getBean(YdmProductDetailBfServiceImpl.class).doAddDetailBf(sum);
					// 2、修改牌号
					detail.setSteelcode(lpp.get(0).getSteel_code());
					detail.setSteel_name(lpp.get(0).getSteel_name());
					this.getMapper(YdmProductDetailMapper.class).update(detail);
				}
				// 整卷发运
				if ("1".equals(lpp.get(0).getWhole_coil())) {

					// 保存相关数据
					// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
					PlnProdorderStatistic pps = new PlnProdorderStatistic();
					pps.setProd_order_no(lpp.get(0).getProd_order_no());
					pps.setReplaced(lypd.get(0).getFactweight());
					pps.setReplaced_cnt(1);
					pps.setReplaced_times(1);
					pps.setUnscheduled(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
					this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

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

					// 调用物流接口，关联实物和生产订单信息
					ypd.setProdorderno(lpp.get(0).getProd_order_no());
					ypd.setOrderno(lpp.get(0).getOrder_no());
					ypd.setCustomer_no(lpp.get(0).getCustomer_no());
					ypd.setCustomer_nm(lpp.get(0).getCustomer_name());
					ypd.setReceiv_nm(lpp.get(0).getReciver_unit_name());
					ypd.setReceiv_no(lpp.get(0).getReciver_unit_no());
					ypd.setDelivery_state_code(lpp.get(0).getDelivery_state_code());
					ypd.setDelivery_state_desc(lpp.get(0).getDelivery_state_desc());
					this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(ypd);

					// 写物料充当脱单履历表[MIL_MAT_REPLACE_LOG] MilMatReplaceLog
					PlnMatReplaceLog mmrl = new PlnMatReplaceLog();
					mmrl.setSerial_no(iNo++);
					mmrl.setObject_no(lypd.get(0).getCoilno());
					mmrl.setOpt_type("2");
					mmrl.setOrder_no(lpp.get(0).getOrder_no());
					mmrl.setProd_order_no(lpp.get(0).getProd_order_no());
					mmrl.setCreate_man_name(userName);
					mmrl.setCreate_time(new Date());
					mmrl.setRemark("整卷发运");
					this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);
				} else {

					// 修改生产订单进程表[PLN_PRODORDER_STATISTIC] 订单进程表
					this.getBean(MesApiDesignInfoImpl.class).updateOrderStatic(lpp.get(0).getProd_order_no(),
							lpp.get(0).getOrder_no(),
							lpp.get(0).getWhole_process_codes(),
							lypd.get(0).getFactweight(), true);

					List<PlnMaterielDetail> pmdetail = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(
							null, " object_no = '" + CoilNo + "' and nvl(invalid_flg,0)=0", null, 0, 1);

					// 调用物流接口，关联实物和生产订单信息
					ypd.setCustomer_no(lpp.get(0).getCustomer_no());
					ypd.setCustomer_nm(lpp.get(0).getCustomer_name());
					ypd.setReceiv_nm(lpp.get(0).getReciver_unit_name());
					ypd.setReceiv_no(lpp.get(0).getReciver_unit_no());
					ypd.setProdorderno(lpp.get(0).getProd_order_no());
					ypd.setOrderno(lpp.get(0).getOrder_no());
					ypd.setObject_no_vt(pmdetail.get(0).getObject_no_vt());
					ypd.setDelivery_state_code(lpp.get(0).getDelivery_state_code());
					ypd.setDelivery_state_desc(lpp.get(0).getDelivery_state_desc());
					this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(ypd);

					// 写物料充当脱单履历表[MIL_MAT_REPLACE_LOG] MilMatReplaceLog
					PlnMatReplaceLog mmrl = new PlnMatReplaceLog();
					BeanUtils.copyProperties(pmdetail.get(0), mmrl);
					mmrl.setSerial_no(iNo++);
					mmrl.setOpt_type("2");
					mmrl.setCreate_man_name(userName);
					mmrl.setCreate_time(new Date());
					mmrl.setRemark("强制挂单,不验证牌号!");
					this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);

					// 生成物料附加信息
					this.getBean(MesApiDesignInfoImpl.class).addMaterielExinfo(lpp.get(0), pmdetail.get(0),
							processpoint.slitting_code);
					
					// 拆分订单如果还需继续生产,判断是否需要移动库存 2019-08-05
					if ((lpp.get(0).getIs_split() != null && "1".equals(lpp.get(0).getIs_split()))) {
						// 如果物料在成品库挪到在制库
						if ("500203".equals(lypd.get(0).getStorageattr())) {
	//						ypd.setStorageattr("500203");
							CommonPage<YdmProductDetail> tmp = new CommonPage<YdmProductDetail>();
							List<YdmProductDetail> ydm = new ArrayList<YdmProductDetail>();
							lypd.get(0).setMemo("拆分订单["+lpp.get(0).getOrder_no()+"]增加["+lpp.get(0).getWhole_process_names()+"]工序->移至在制库");
							ydm.add(lypd.get(0));
							tmp.setObjectList(ydm);
							tmp.setMemo1("500202");
							tmp.setMemo2("0");
							this.getBean(LmsApiServiceImpl.class).doChangeMaterialStorage(tmp);
						}
					}
				}

				ResultModel rejRes = this.getBean(SlmFundFirstDetailService.class).reAutoUltiJudge(CoilNo);
				if (!"200".equals(rejRes.getState())) {
					throw new Exception(rejRes.getMsgInfo());
				}
			}
		} else {
//			// 处理逻辑2
//			if ("0PAA12".compareTo(lpp.get(0).getStatus()) <= 0) {
//				rm.setState("500");
//				rm.setMsgInfo("[原料卷/非计划]的订单，必须在下发生产前充当！");
//				return rm;
//			}

			for (String CoilNo : sCoilNo) {
				// 处理逻辑
				// 对传入的实物卷，查询库存信息[物流接口]
				// 存在信息，则读取之； 若不存在信息，则报错“库存中无实物[xxx]信息”
				CommonPage<YdmProductDetail> cp = new CommonPage<YdmProductDetail>();
				YdmProductDetail ypd = new YdmProductDetail();
				ypd.setCoilno(CoilNo);
				cp.setObject(ypd);
				ResultModel rmValid = this.getBean(LmsApiServiceImpl.class).doFindCoilno(cp);
				if (!"200".equals(rmValid.getState())) {
					throw new Exception(rmValid.getMsgInfo());
				}

				// 挂单后判断该卷是否已经iscanload：是 就置为null，让其重新判断iscanload；20230210刘侣
				YdmProductDetail ypdCanLoad = new YdmProductDetail();
				ypdCanLoad.setCoilno(CoilNo);
				ypdCanLoad.setIs_can_load("1");
				List<YdmProductDetail> ypdCanList = this.getMapper(YdmProductDetailMapper.class).find(ypdCanLoad, 0, 0);
				if (ypdCanList != null && ypdCanList.size() > 0) {
					ypdCanList.get(0).setIs_can_load("0");
					this.getMapper(YdmProductDetailMapper.class).update(ypdCanList.get(0));
					this.getMapper(YdmProductDetailMapper.class).kctbYdd(ypdCanList.get(0).getCoilno());
				}
				// end
				
				// 2018-06-15 限制重复挂单加此操作
				@SuppressWarnings("unchecked")
				List<YdmProductDetail> lypd = (List<YdmProductDetail>) rmValid.getData();
				for (YdmProductDetail ydmp : lypd) {
					if (ydmp.getOrderno() != null) {
						rm.setState("500");
						rm.setMsgInfo(
								"实物[" + cp.getObject().getCoilno() + "]已绑定订单[" + ydmp.getOrderno() + "]! 不能再次操作!");
					} else if(!flag_c && !flag_j){
						PlnMaterielDetail pmd = new PlnMaterielDetail();
						pmd.setObject_no(ydmp.getCoilno());
						List<PlnMaterielDetail> pmdd = this.getMapper(PlnMaterielDetailMapper.class)
								.findWithCondition(pmd, "nvl(invalid_flg,0) = 0", "", 0, 0);
						if (pmdd != null && pmdd.size() > 0) {
							for (PlnMaterielDetail plnmaterieldetail : pmdd) {
								plnmaterieldetail.setObject_no("");
								this.getMapper(PlnMaterielDetailMapper.class).update(plnmaterieldetail);
							}
						}
					}
				}


				
				// 如果牌号不匹配
				if (!lpp.get(0).getSteel_code().equals(lypd.get(0).getJudgesteelcode()) || !lpp.get(0).getSteel_code().equals(lypd.get(0).getSteelcode())) {
					// 1、备份库存信息
					CommonPage<YdmProductDetail> sum = new CommonPage<YdmProductDetail>();
					YdmProductDetail detail = new YdmProductDetail();
					detail.setCoilno(CoilNo);
					List<YdmProductDetail> ydmlist = new ArrayList<YdmProductDetail>();
					ydmlist.add(detail);
					sum.setObjectList(ydmlist);
					this.getBean(YdmProductDetailBfServiceImpl.class).doAddDetailBf(sum);
					// 2、修改牌号
					detail.setSteelcode(lpp.get(0).getSteel_code());
					detail.setSteel_name(lpp.get(0).getSteel_name());
					this.getMapper(YdmProductDetailMapper.class).update(detail);
				}
				
				// 保存相关数据
				// 修改生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic pps = new PlnProdorderStatistic();
				pps.setProd_order_no(lpp.get(0).getProd_order_no());
				pps.setReplaced(lypd.get(0).getFactweight());
				pps.setReplaced_cnt(1);
				pps.setReplaced_times(1);
				pps.setUnscheduled(lypd.get(0).getFactweight() == null ? null : (-lypd.get(0).getFactweight()));
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);

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

				// 调用物流接口，关联实物和生产订单信息
				ypd.setProdorderno(pps.getProd_order_no());
				ypd.setOrderno(pos.getOrder_no());
				ypd.setCustomer_no(lpp.get(0).getCustomer_no());
				ypd.setCustomer_nm(lpp.get(0).getCustomer_name());
				ypd.setReceiv_nm(lpp.get(0).getReciver_unit_name());
				ypd.setReceiv_no(lpp.get(0).getReciver_unit_no());
				ypd.setDelivery_state_code(lpp.get(0).getDelivery_state_code());
				ypd.setDelivery_state_desc(lpp.get(0).getDelivery_state_desc());
				this.getMapper(YdmProductDetailMapper.class).doFinshedProductActUpdate(ypd);

				// 写物料充当脱单履历表[MIL_MAT_REPLACE_LOG] MilMatReplaceLog
				PlnMatReplaceLog mmrl = new PlnMatReplaceLog();
				mmrl.setSerial_no(iNo++);
				mmrl.setObject_no(lypd.get(0).getCoilno());
				mmrl.setOpt_type("1");
				mmrl.setOrder_no(pos.getOrder_no());
				mmrl.setProd_order_no(pps.getProd_order_no());
				mmrl.setCreate_man_name(userName);
				mmrl.setCreate_time(new Date());
				mmrl.setRemark("强制挂单,不验证牌号!");
				this.getMapper(PlnMatReplaceLogMapper.class).insert(mmrl);

				ResultModel rejRes = this.getBean(SlmFundFirstDetailService.class).reAutoUltiJudge(CoilNo);
				if (!"200".equals(rejRes.getState())) {
					throw new Exception(rejRes.getMsgInfo());
				}
				
			}
		}
		//日志
		MesOprLog mol = new MesOprLog("生产管理", "小纵剪不检验牌号挂单管理", "挂单", username, opr_time, null, null, null, null, Arrays.toString(sCoilNo));
		this.getMapper(MesOprLogMapper.class).insert(mol);
		rm.setState("200");
		return rm;
	}
	
	
	
	
	
	
	//--------------------------------后面的代码不要了----------------------------
	/**
	 * 查询已设计方案
	 * memo1 外径最小值
	 * memo2 外径最大值
	 * memo3 合同号 
	 * startTime 开始时间
	 * endTime 设计设计结束时间
	 * */
	public ResultModel doQueryDesigned(CommonPage<PlnLengthwiseDsnMain> sum){
		ResultModel rm=new ResultModel();
		try{
			PlnLengthwiseDsnMain pldm=sum.getObject()==null?(new PlnLengthwiseDsnMain()):sum.getObject();
			String sWhere2="",sWhere3="";
			
			if(sum.getMemo1()!=null&&!"".equals(sum.getMemo1())){
				sWhere2+=" and t1.diameter_out>="+sum.getMemo1();
			}
			if(sum.getMemo2()!=null&&!"".equals(sum.getMemo2())){
				sWhere2+=" and t1.diameter_out<="+sum.getMemo2();
			}
			
			if(sum.getMemo3()!=null&&!"".equals(sum.getMemo3())){
				sWhere3+=" and t3.contract_no like '%"+sum.getMemo3().trim()+"%' ";
			}
			
			
			rm.setData(this.getMapper(PlnLengthwiseDsnMainMapper.class).doQueryCompleteDsn(sWhere2, sWhere3, sum.getStartTime(), sum.getEndTime(), pldm));
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
	
	/**
	 * 保存设计方案
	 * List<clsScheme>
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doSaveDesignInfo(CommonPage<clsScheme> oci){
		ResultModel rm=new ResultModel();
		// 工序点信息
		List<ComBaseInfo> infoI = this.getMapper(ComBaseInfoMapper.class)
				.findWithCondition(null, "sort_code = '2002' AND validflag = '1'",
						null, 0, 0);
		ProcessPoint processpoint = new ProcessPoint(infoI);
		String sDate=new SimpleDateFormat("yyMMdd").format(new Date());
		
		List<clsScheme> schemes=oci.getObjectList();
		
		//主设计
		PlnLengthwiseDsnMain pldm=new PlnLengthwiseDsnMain();
		List<PlnLengthwiseDsnMain> lpdmNo=this.getMapper(PlnLengthwiseDsnMainMapper.class).findWithCondition(null, "", " serial_no desc ", 0, 1);
		//long No=this.getMapper(PlnLengthwiseDsnMainMapper.class).doQueryMaxNo();
		pldm.setLw_design_no("DLW"+sDate+String.format("%06d", 1));
		if(lpdmNo!=null&&lpdmNo.size()>0){
			pldm.setSerial_no(lpdmNo.get(0).getSerial_no()+1);
			if(sDate.equals(lpdmNo.get(0).getLw_design_no().substring(3,9))){
				pldm.setLw_design_no("DLW"+sDate+String.format("%06d", Integer.parseInt(lpdmNo.get(0).getLw_design_no().substring(9,15))+1 ));
			}
		}
		
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		//倒叙去一条
		List<PlnLengthwiseDsnMultinfo> lpdmM=this.getMapper(PlnLengthwiseDsnMultinfoMapper.class).findWithCondition(null, "", " serial_no desc ", 0,1);
		long DsnNo=1;
		if(lpdmM!=null&&lpdmM.size()>0){
			DsnNo=lpdmM.get(0).getSerial_no()+1;
		}
		
		//倒叙去一条
		List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null, "", " serial_no desc ", 0,1);
		long PMDNo=1;
		
		if(lpmd!=null&&lpmd.size()>0){
			PMDNo=lpmd.get(0).getSerial_no()+1;
		}
		
		List<PlnDsnOrderInfo> lpdoiq=this.getMapper(PlnDsnOrderInfoMapper.class).findWithCondition(null, "", " serial_no desc", 0, 1);
		long pdoiNo=1;
		if(lpdoiq!=null&&lpdoiq.size()>0){
			pdoiNo=lpdoiq.get(0).getSerial_no()+1;
		}
		
		int objectnoVtNo=this.getMapper(PlnMaterielDetailMapper.class).getObjectVtMaxNoForDate(sDate)+1;
	
		
		clsScheme scheme=schemes.get(0);
		
		//-----------------主设计---------------------
		//填写第一个订单的信息
		PlnProdorder pp=new PlnProdorder();
		pp.setProd_order_no(scheme.getDetails().get(0).getOrder_no());
		List<PlnProdorder> lpp=this.getMapper(PlnProdorderMapper.class).find(pp, 0, 0);
		pldm.setProd_order_no(lpp.get(0).getProd_order_no());
		pldm.setOrder_no(lpp.get(0).getOrder_no());
		pldm.setPline_code(lpp.get(0).getPline_code());
		pldm.setSteel_code(lpp.get(0).getSteel_code());
		
		String isMulti="0";//是否拼料 根据订单数判断，多个订单填1，否则填0
		pldm.setIs_multi(isMulti);
		
		pldm.setMat_diameter_inn(scheme.getInner_diam());
		pldm.setMat_diameter_out(scheme.getOutter_diam());
		pldm.setMat_single_weight(scheme.getSingle_wgt());
		pldm.setMat_width(scheme.getWidth());
		pldm.setProd_rate(scheme.getTimber_rate());
		
		int subCount=0;
		for(clsSchemeDetail c:scheme.getDetails()){
			subCount+=c.getSub_coil_cnt();
		}
		pldm.setSub_count(subCount);
		
		pldm.setMat_thick(lpp.get(0).getThick());
		pldm.setMat_length(lpp.get(0).getLength());
		pldm.setFixed_length_type_no(lpp.get(0).getFixed_length_type_no());
		pldm.setCut_style(scheme.getCut_style());
		pldm.setCut_edge_type_no(lpp.get(0).getCut_edge_type_no());
		
		pldm.setDesign_quantity(scheme.getCoil_cnt());
		pldm.setDesign_weight(scheme.getSingle_wgt()*scheme.getCoil_cnt());
		
		//非拼料填写生产订单成品数据
		/*if("0".equals(isMulti)){
			//通过计算获取
			pldm.setLength(GetLength(scheme.getInner_diam(),scheme.getOutter_diam(),lpp.get(0).getThick()));
			
			
			pldm.setThick(lpp.get(0).getThick());
			pldm.setWidth(lpp.get(0).getWidth());
			pldm.setDiameter_inn(lpp.get(0).getDiameter_inn());
			pldm.setDiameter_out(lpp.get(0).getDiameter_out());
			pldm.setDeliver_date(lpp.get(0).getDeliver_date());
		}*/
		pldm.setCreate_man_name(userName);
		pldm.setCreate_time(new Date());
		pldm.setIs_finished(0);
		
		//-----------------主设计---------------------
		
		
		Date Deliver_date_earliest=null,Deliver_date_latest=null;
		for(int j=0;j<scheme.getCoil_cnt();j++){
			//--------------------母卷虚拟信息----------------
			//母卷虚拟物料数据
			PlnMaterielDetail pmdM=new PlnMaterielDetail();
			pmdM.setSerial_no(PMDNo++);
			pmdM.setStatus("0PDA10");
			pmdM.setPline_code(lpp.get(0).getPline_code());
			
			pmdM.setObject_type("1");
			
			pmdM.setIs_prev_dsn_finished("0");//母卷：0
			pmdM.setCreate_design_no(pldm.getLw_design_no());
			pmdM.setCreate_process_code(processpoint.slitting_code);
			pmdM.setIs_mat(1);//母卷：1
			pmdM.setObject_no_vt(sDate+String.format("%06d", objectnoVtNo++));
			pmdM.setOrder_no(lpp.get(0).getOrder_no());
			pmdM.setProd_order_no(lpp.get(0).getProd_order_no());
			pmdM.setLw_design_no(pldm.getLw_design_no());
			pmdM.setIs_multi(isMulti);
			pmdM.setSteel_code(lpp.get(0).getSteel_code());
			
			pmdM.setWidth(pldm.getMat_width());
			pmdM.setThick(pldm.getMat_thick());
			pmdM.setLength(pldm.getMat_length());
			pmdM.setDiameter_inn(pldm.getMat_diameter_inn());
			pmdM.setDiameter_out(pldm.getMat_diameter_out());
			pmdM.setSingle_weight(pldm.getMat_single_weight());
			
			pmdM.setFixed_length_type_no(pldm.getFixed_length_type_no());
			pmdM.setCut_edge_type_no(pldm.getCut_edge_type_no());
			pmdM.setCreate_man_name(userName);
			pmdM.setCreate_time(new Date());
			
			pmdM.setPrev_dsn_process_code(null);
			pmdM.setPrev_process_code(null);
			pmdM.setNext_dsn_process_code(processpoint.slitting_code);
			pmdM.setNext_process_code(processpoint.slitting_code);
			
			String orderNo="";
			//------------------------------------------------------------
			int seq=1;
			//---------------------订单----------------------------
			for(int m=0;m<scheme.getDetails().size();m++){
				double weight_in_one=0;
				int quantity_in_one=0;
				
				PlnProdorder ppq=new PlnProdorder();
				ppq.setProd_order_no(scheme.getDetails().get(m).getOrder_no());
				List<PlnProdorder> lppq=this.getMapper(PlnProdorderMapper.class).find(ppq, 0, 1);
				
				//-----------------------子卷---------------------------------------------------
				for(int k=0;k<scheme.getDetails().get(m).getSub_coil_cnt();k++){
					weight_in_one+=scheme.getDetails().get(m).getWeight();
					quantity_in_one++;
					if(j==0){
						
						//-----------------写拼料-----------------------------
						PlnLengthwiseDsnMultinfo pldmc=new PlnLengthwiseDsnMultinfo();
						pldmc.setSerial_no(DsnNo++);
						pldmc.setSub_seq(seq++);
						pldmc.setWidth(scheme.getDetails().get(m).getWidth());
						pldmc.setWeight(scheme.getDetails().get(m).getWeight());
						pldmc.setLw_design_no(pldm.getLw_design_no());
						pldmc.setDiameter_inn(scheme.getInner_diam());
						pldmc.setDiameter_out(scheme.getOutter_diam());
						
						//同一个厚度才能一起所以取订单的即可
						pldmc.setThick(lppq.get(0).getThick());
						//通过计算获取
						pldmc.setLength(GetLength(scheme.getInner_diam(),scheme.getOutter_diam(),lppq.get(0).getThick()));
						
						pldmc.setOrder_no(lppq.get(0).getOrder_no());
						pldmc.setProd_order_no(lppq.get(0).getProd_order_no());
						pldmc.setFixed_length_type_no(lppq.get(0).getFixed_length_type_no());
						pldmc.setCut_edge_type_no(lppq.get(0).getCut_edge_type_no());
						
					
						this.getMapper(PlnLengthwiseDsnMultinfoMapper.class).insert(pldmc);
						//---------------------------------------------------
					}
					
					PlnMaterielDetail pmdc=new PlnMaterielDetail();
					pmdc.setSerial_no(PMDNo++);
					pmdc.setStatus("0PDA10");
					pmdc.setPline_code(lppq.get(0).getPline_code());
					
					pmdc.setObject_type("1");
					
					pmdc.setIs_prev_dsn_finished("1");//母卷：0
					pmdc.setCreate_design_no(pldm.getLw_design_no());
					pmdc.setCreate_process_code(processpoint.slitting_code);
					pmdc.setIs_mat(0);//母卷：1
					pmdc.setObject_no_vt(sDate+String.format("%06d", objectnoVtNo++));
					pmdc.setOrder_no(lppq.get(0).getOrder_no());
					pmdc.setProd_order_no(lppq.get(0).getProd_order_no());
					pmdc.setLw_design_no(pldm.getLw_design_no());
					pmdc.setIs_multi(isMulti);
					pmdc.setSteel_code(lppq.get(0).getSteel_code());
					
					pmdc.setPrev_dsn_process_code(processpoint.slitting_code);
					pmdc.setPrev_process_code(processpoint.slitting_code);
					pmdc.setNext_dsn_process_code(null);
					pmdc.setNext_process_code("60001");
					 
					pmdc.setWidth(scheme.getDetails().get(m).getWidth());
					pmdc.setThick(pldm.getMat_thick());
					pmdc.setLength(pldm.getMat_length());
					pmdc.setDiameter_inn(pldm.getMat_diameter_inn());
					pmdc.setDiameter_out(pldm.getMat_diameter_out());
					pmdc.setSingle_weight(scheme.getDetails().get(m).getWeight());
					
					pmdc.setFixed_length_type_no(pldm.getFixed_length_type_no());
					pmdc.setCut_edge_type_no(pldm.getCut_edge_type_no());
					pmdc.setCreate_man_name(userName);
					pmdc.setCreate_time(new Date());
					pmdc.setMat_object_no_vt(pmdM.getObject_no_vt());
					
					
					pmdc.setDeliver_date_earliest(lppq.get(0).getDeliver_date());
					pmdc.setDeliver_date_latest(lppq.get(0).getDeliver_date());
					
					this.getMapper(PlnMaterielDetailMapper.class).insert(pmdc);
				}
				
				//--------------------------------------------------------------------------
				
				if(j==0){
					PlnDsnOrderInfo pdoi=new PlnDsnOrderInfo();
					pdoi.setSerial_no(pdoiNo++);
					pdoi.setDesign_no(pldm.getLw_design_no());
					pdoi.setProd_order_no(scheme.getDetails().get(m).getOrder_no());
					
					pdoi.setOrder_no(lppq.get(0).getOrder_no());
					
					pdoi.setWeight_in_one(weight_in_one);
					pdoi.setQuantity_in_one(quantity_in_one);
					this.getMapper(PlnDsnOrderInfoMapper.class).insert(pdoi);
				}
				
				
				PlnOrderStatistic pos=new PlnOrderStatistic();
				pos.setOrder_no(lppq.get(0).getOrder_no());
				pos.setLw_dsn(weight_in_one);
				pos.setLw_dsn_cnt(quantity_in_one);
				this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
				
				PlnProdorderStatistic pps=new PlnProdorderStatistic();
				pps.setProd_order_no(scheme.getDetails().get(m).getOrder_no());
				pps.setLw_dsn(weight_in_one);
				pps.setLw_undsn(-weight_in_one);
				pps.setLw_dsn_cnt(quantity_in_one);
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
				
				if(!orderNo.equals(lppq.get(0).getOrder_no())){
					if(pmdM.getDeliver_date_earliest()==null){
						pmdM.setDeliver_date_earliest(lppq.get(0).getDeliver_date());
						pmdM.setDeliver_date_latest(lppq.get(0).getDeliver_date());
						Deliver_date_earliest=pmdM.getDeliver_date_earliest();
						Deliver_date_latest=pmdM.getDeliver_date_latest();
					}else{
						if(pmdM.getDeliver_date_earliest().getTime()>lppq.get(0).getDeliver_date().getTime()){
							pmdM.setDeliver_date_earliest(lppq.get(0).getDeliver_date());
							Deliver_date_earliest=pmdM.getDeliver_date_earliest();
						}
						if(pmdM.getDeliver_date_latest().getTime()<lppq.get(0).getDeliver_date().getTime()){
							pmdM.setDeliver_date_latest(lppq.get(0).getDeliver_date());
							Deliver_date_latest=pmdM.getDeliver_date_latest();
						}
					}
				}
			}
			//------------------------------------------------------------
			
			//-------------新增虚拟母卷，由于要运算时间所以丢最后------------------------------
			pmdM.setDeliver_date_earliest(Deliver_date_earliest);
			pmdM.setDeliver_date_latest(Deliver_date_latest);
			this.getMapper(PlnMaterielDetailMapper.class).insert(pmdM);
		}
		
		this.getMapper(PlnLengthwiseDsnMainMapper.class).insert(pldm);
		
		rm.setState("200");
		rm.setData(pldm.getLw_design_no());
		return rm;
	}
	
	/**
	 * 保存是获取长度
	 * length=  体积 / 厚度 / 宽度   = (     Pi * ( 外径/2 )^2   -  Pi * ( 内径/2 )^2    )  /  厚度
	 * */
	private static double GetLength(double inner, double outter,double thick){
        return (Math.PI * Math.pow(outter / 2, 2) - Math.PI * Math.pow(inner / 2, 2))/thick;
	}
	
	/**
	 * 删除母卷
	 * 传入 虚拟母卷号
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doCancelDesigns(CommonPage<PlnMaterielDetail> oci) throws Exception{
		ResultModel rm=new ResultModel();
		List<PlnMaterielDetail> lpmd=oci.getObjectList();
		if(lpmd==null){
			rm.setState("500");
			rm.setMsgInfo("请传入虚拟母卷号!");
			return rm;
		}
		doCancelChild(lpmd);
		
		rm.setState("200");
		return rm;
	}
	
	/**
	 * 删除设计
	 * 传入的设计号 create_design_no
	 * @throws Exception 
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doCancelDesign(CommonPage<PlnMaterielDetail> oci) throws Exception{
		ResultModel rm=new ResultModel();
		//根据传入的设计号，查找虚拟物料表【PLN_MATERIEL_DETAIL】
		if(oci.getObject()==null){
			rm.setState("500");
			rm.setMsgInfo("请传入设计号!");
			return rm;
		}
		oci.getObject().setIs_mat(1);
		List<PlnMaterielDetail> lpmd=this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(oci.getObject(), "", " object_no_vt ", 0, 0);
		if(lpmd==null){
			rm.setState("500");
			rm.setMsgInfo("未找到虚拟母卷!");
			return rm;
		}
		doCancelChild(lpmd);
		rm.setState("200");
		return rm;
	}
	
	/**
	 * 删除卷子方法
	 * @throws Exception 
	 * */
	private void doCancelChild(List<PlnMaterielDetail> lpmd) throws Exception{
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		for(PlnMaterielDetail pmd:lpmd){
			//读取虚拟物料表【PLN_MATERIEL_DETAIL】，获取虚拟母卷信息
			List<PlnMaterielDetail> lpmdq=this.getMapper(PlnMaterielDetailMapper.class).find(pmd, 0, 1);
			if(lpmdq==null||lpmdq.size()==0){
				throw new Exception("未找到虚拟物料["+pmd.getObject_no_vt()+"]");
			}
			//判断虚拟母卷是否进行了上一工序坯料设计: 如果【PREV_DSN_PROCESS_CODE】不空，则报错退出
			if(lpmdq.get(0).getPrev_dsn_process_code()!=null&&!"".equals(lpmdq.get(0).getPrev_dsn_process_code())){
				throw new Exception("虚拟物料["+pmd.getObject_no_vt()+"]已经作了上一工序的母料设计，无法删除！");
			}
			//判断虚拟母卷是否绑定了实物: IF(OBJECT_NO = ""),如果不成立，则报错退出
			if(lpmdq.get(0).getObject_no()!=null&&!"".equals(lpmdq.get(0).getObject_no())){
				throw new Exception("虚拟物料["+pmd.getObject_no_vt()+"]已绑定实物，无法删除！");
			}
			//判断虚拟母卷是否进行过生产：IF(OPT_TIMES>0 OR NEED_EXTOPT >0 ),如果成立，则报错退出
			if((lpmdq.get(0).getOpt_times()!=null && lpmdq.get(0).getOpt_times()>0) ||
					(lpmdq.get(0).getNeed_extopt()!=null && "0".compareTo(lpmdq.get(0).getNeed_extopt())<0)){
				throw new Exception("虚拟物料["+pmd.getObject_no_vt()+"]已进行过生产，无法删除！");
			}
			//判断以下字段是否有值
			if(lpmdq.get(0).getLw_plan_no()!=null&&!"".equals(lpmdq.get(0).getLw_plan_no())){
				throw new Exception("虚拟物料["+pmd.getObject_no_vt()+"]已做分条计划，无法删除！");
			}
			if(lpmdq.get(0).getCl_plan_no()!=null&&!"".equals(lpmdq.get(0).getCl_plan_no())){
				throw new Exception("虚拟物料["+pmd.getObject_no_vt()+"]已做横剪计划，无法删除！");
			}
			if(lpmdq.get(0).getRl_plan_no()!=null&&!"".equals(lpmdq.get(0).getRl_plan_no())){
				throw new Exception("虚拟物料["+pmd.getObject_no_vt()+"]已做轧制计划，无法删除！");
			}
			
			//循环处理 该虚拟母卷对应的 所有虚拟子卷
			PlnMaterielDetail pmdcq=new PlnMaterielDetail();
			pmdcq.setMat_object_no_vt(lpmdq.get(0).getObject_no_vt());
			List<PlnMaterielDetail> lpmdc=this.getMapper(PlnMaterielDetailMapper.class).find(pmdcq, 0, 0);
			for(PlnMaterielDetail pmdc:lpmdc){
				//如果虚拟子卷的[NEXT_DSN_PROCESS_CODE]==null 或 =="", 则 删除虚拟子卷。
				if(pmdc.getNext_dsn_process_code()==null || "".equals(pmdc.getNext_dsn_process_code())){
					this.getMapper(PlnMaterielDetailMapper.class).doDeleteId(pmdc);
				}else{
					//将虚拟子卷的   MAT_OBJECT_NO 置为 NULL;   LW_DESIGN_NO 分条设计号置为 NULL;   IS_PREV_DSN_FINISHED 上道工序设计已完成=null
					this.getMapper(PlnMaterielDetailMapper.class).doUpdateCancelDesigns(pmdc);
					//新增虚拟子卷的 虚拟物料履历表
					this.getBean(MesApiServiceImpl.class).InsertMatVtProc(pmdc.getObject_no_vt(),pmdc.getStatus(),userName,new Date());
				}
			}
			
			//删除虚拟母卷信息
			this.getMapper(PlnMaterielDetailMapper.class).doDeleteId(lpmdq.get(0));
			
			//根据母卷 生成的设计工序【CREATE_PROCESS_CODE】判断  == ‘分条工序代码’
			if(this.getBean(QmsApiServiceImpl.class).GetWrkPlanCode(lpmdc.get(0).getOrder_no()).equals(lpmdq.get(0).getCreate_process_code())){
				//根据 虚拟母卷的 生成时的设计号CREATE_DESIGN_NO，修改对应 分条设计主表记录
				// DESIGN_QUANTITY 设计原料卷总数 -= 1;  DESIGN_WEIGHT 设计原料卷总重 -= MAT_SINGLE_WEIGHT 原料卷单重
				PlnLengthwiseDsnMain pldm=new PlnLengthwiseDsnMain();
				pldm.setLw_design_no(lpmdq.get(0).getCreate_design_no());
				pldm.setDesign_quantity(-1);
				this.getMapper(PlnLengthwiseDsnMainMapper.class).doUpdatePlanedWgt(pldm);
			}
			
			//保存订单跟踪信息
			//修改对应 订单进程表[PLN_ORDER_STATISTIC]
			/*PlnOrderStatistic poscs=new PlnOrderStatistic();
			poscs.setOrder_no(pmd.getOrder_no());
			poscs.setLw_dsn();
			poscs.setLw_dsn_cnt(-v_total_num);
			poscs.setLw_undsn(pmd.getSingle_weight());
			this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(poscs);
			
			//修改对应 生产订单进程表[PLN_PRODORDER_STATISTIC]
			PlnProdorderStatistic ppscs=new PlnProdorderStatistic();
			ppscs.setProd_order_no(pmd.getProd_order_no());
			ppscs.setLw_dsn(-v_total_wgt);
			ppscs.setLw_dsn_cnt(-v_total_num);
			ppscs.setLw_undsn(pmd.getSingle_weight());
			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(ppscs);*/
			
			//根据母卷的【CREATE_DESIGN_NO】, 读取【pln_dsn_order_info】中的所有数据
			PlnDsnOrderInfo pdoi=new PlnDsnOrderInfo();
			pdoi.setDesign_no(lpmdq.get(0).getCreate_design_no());
			List<PlnDsnOrderInfo> lpdoi=this.getMapper(PlnDsnOrderInfoMapper.class).find(pdoi, 0, 0);
			for(PlnDsnOrderInfo p:lpdoi){
				//根据S2的 生产订单号，修改对应 生产订单进程表[PLN_PRODORDER_STATISTIC]
				PlnProdorderStatistic ppsc=new PlnProdorderStatistic();
				ppsc.setProd_order_no(p.getProd_order_no());
				ppsc.setLw_dsn(-p.getWeight_in_one());
				ppsc.setLw_dsn_cnt(-p.getQuantity_in_one());
				ppsc.setLw_undsn(p.getWeight_in_one());
				ppsc.setLw_undsn_cnt(p.getQuantity_in_one());
				this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(ppsc);
			
				//根据S2的 订单号，修改对应 订单进程表[PLN_ORDER_STATISTIC]
				PlnOrderStatistic posc=new PlnOrderStatistic();
				posc.setOrder_no(p.getOrder_no());
				ppsc.setLw_dsn(-p.getWeight_in_one());
				ppsc.setLw_dsn_cnt(-p.getQuantity_in_one());
				ppsc.setLw_undsn(p.getWeight_in_one());
				ppsc.setLw_undsn_cnt(p.getQuantity_in_one());
				this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(posc);
			}
			
			//(临时变量：v_设计号 = 虚拟母卷的CREATE_DESIGN_NO)
			String v_dsn_no=lpmdq.get(0).getCreate_design_no();
			//统计虚拟物料表中,母卷设计号对应的母板个数
			PlnMaterielDetail pmdcount=new PlnMaterielDetail();
			pmdcount.setCreate_design_no(v_dsn_no);
			pmdcount.setIs_mat(1);
			int icount=this.getMapper(PlnMaterielDetailMapper.class).count(pmdcount);
			//如果 (统计个数 == 0
			if(icount==0){
				//删除 分条拼料信息表【PLN_LENGTHWISE_DSN_MULTINFO】: where LW_DESIGN_NO = v_设计号
				this.getMapper(PlnLengthwiseDsnMultinfoMapper.class).doDelete(v_dsn_no);
				
				//删除 分条设计主表【PLN_LENGTHWISE_DSN_MAIN】: where LW_DESIGN_NO = v_设计号
				PlnLengthwiseDsnMain pldm=new PlnLengthwiseDsnMain();
				pldm.setLw_design_no(v_dsn_no);
				this.getMapper(PlnLengthwiseDsnMainMapper.class).doDelete(pldm);
				
				//删除 坯料设计订单组成表【PLN_DSN_ORDER_INFO】: where DESIGN_NO = v_设计号
				PlnDsnOrderInfo pdoid=new PlnDsnOrderInfo();
				pdoid.setDesign_no(v_dsn_no);
				this.getMapper(PlnDsnOrderInfoMapper.class).doDelete(pdoid);
				
			}
		}
	}
	
	/**
	 * 取消设计方案
	 * */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public ResultModel doCancelDesignInfo(CommonPage<PlnLengthwiseDsnMain> oci){
		ResultModel rm=new ResultModel();
		
		//订单进程表
		List<PlnOrderStatistic> lpos=new ArrayList<PlnOrderStatistic>();
		//生产订单进程表
		List<PlnProdorderStatistic> lpps=new ArrayList<PlnProdorderStatistic>();
		
		for(PlnLengthwiseDsnMain pldm:oci.getObjectList()){
			PlnLengthwiseDsnMain pdm=new PlnLengthwiseDsnMain();
			pdm.setLw_design_no(pldm.getLw_design_no());
			int icount=this.getMapper(PlnLengthwiseDsnMainMapper.class).countWithCondition(pdm, " STATUS!='0PBA10' ");
			if(icount>0){
				rm.setState("500");
				rm.setMsgInfo("存在虚拟物料的状态已经排产或进行上道工序设计，不能删除");
				return rm;
			}
		
			//根据设计编号group by 统计订单进程、生产订单进程信息
			//订单进程表
			List<HashMap> lposQ=this.getMapper(PlnMaterielDetailMapper.class).doSumOrderForDsnNo(pldm);
			for(HashMap pmd:lposQ){
				if(lpos.size()==0){
					PlnOrderStatistic pos=new PlnOrderStatistic();
					pos.setOrder_no((String) pmd.get("ORDER_NO"));
					pos.setLw_dsn(-(Double)pmd.get("V_WEIGHT"));
					pos.setLw_dsn_cnt(-(Integer)pmd.get("V_COUNT"));
					pos.setLw_undsn((Double)pmd.get("V_WEIGHT"));
					lpos.add(pos);
				}else{
					boolean flag=false;
					for(PlnOrderStatistic posc:lpos){
						if(posc.getOrder_no().equals((String) pmd.get("ORDER_NO"))){
							posc.setLw_dsn(posc.getLw_dsn()-(Double)pmd.get("V_WEIGHT"));
							posc.setLw_dsn_cnt(posc.getLw_dsn_cnt()-(Integer)pmd.get("V_COUNT"));
							posc.setLw_undsn(posc.getLw_undsn()+(Double)pmd.get("V_WEIGHT"));
							flag=true;
						}
					}
					if(!flag){
						PlnOrderStatistic pos=new PlnOrderStatistic();
						pos.setOrder_no((String) pmd.get("ORDER_NO"));
						pos.setLw_dsn(-(Double)pmd.get("V_WEIGHT"));
						pos.setLw_dsn_cnt(-(Integer)pmd.get("V_COUNT"));
						pos.setLw_undsn((Double)pmd.get("V_WEIGHT"));
						lpos.add(pos);
					}
				}
			}
			
			//生产订单进程表
			List<HashMap> lppsQ=this.getMapper(PlnMaterielDetailMapper.class).doSumProdOrderForDsnNo(pldm);
			for(HashMap pmd:lppsQ){
				if(lpps.size()==0){
					PlnProdorderStatistic pps=new PlnProdorderStatistic();
					pps.setProd_order_no((String) pmd.get("PROD_ORDER_NO"));
					pps.setLw_dsn(-(Double)pmd.get("V_WEIGHT"));
					pps.setLw_dsn_cnt(-(Integer)pmd.get("V_COUNT"));
					pps.setLw_undsn((Double)pmd.get("V_WEIGHT"));
					lpps.add(pps);
				}else{
					boolean flag=false;
					for(PlnProdorderStatistic ppsc:lpps){
						if(ppsc.getProd_order_no().equals((String) pmd.get("PROD_ORDER_NO"))){
							ppsc.setLw_dsn(ppsc.getLw_dsn()-(Double)pmd.get("V_WEIGHT"));
							ppsc.setLw_dsn_cnt(ppsc.getLw_dsn_cnt()-(Integer)pmd.get("V_COUNT"));
							ppsc.setLw_undsn(ppsc.getLw_undsn()+(Double)pmd.get("V_WEIGHT"));
							flag=true;
						}
					}
					if(!flag){
						PlnProdorderStatistic pps=new PlnProdorderStatistic();
						pps.setOrder_no((String) pmd.get("ORDER_NO"));
						pps.setLw_dsn(-(Double)pmd.get("V_WEIGHT"));
						pps.setLw_dsn_cnt(-(Integer)pmd.get("V_COUNT"));
						pps.setLw_undsn((Double)pmd.get("V_WEIGHT"));
						lpps.add(pps);
					}
				}
			}
		}
		
		//修改进程跟踪表
		for(PlnOrderStatistic pos:lpos){
			//订单进程表
			this.getMapper(PlnOrderStatisticMapper.class).doUpdatePlaned(pos);
		}
		for(PlnProdorderStatistic pps:lpps){
			//生产订单进程表
			this.getMapper(PlnProdorderStatisticMapper.class).doUpdatePlaned(pps);
		}
		
		rm.setState("200");
		return rm;
	}
	
	
	//*************************************以下是自动设计代码*************************************
	private ClsRestrict MachineRestrict;
	private static int MaxScheme = 50; //保留最大方案数
	private static List<clsScheme> All_Schemes = new ArrayList<clsScheme>();
	//private delegate ArrayList delegate_Calc(ArrayList orders, ArrayList param, int thread_serial, int total_thread_serial);
	
	/**
	 * 自动设计 
	 * memo1 内径
	 * memo2 外径
	 * memo3 宽度
	 * */
	public ResultModel doAutomaticDesignWeb(CommonPage<PlnProdorder> oci){
		ResultModel rm=new ResultModel();
		List<PlnProdorder> lpldm=oci.getObjectList();
		
		//生产订单进程表
		PlnProdorderStatistic pos=new PlnProdorderStatistic();
		
		//检索表中订单的数据，比较所选订单的厚度、牌号、工艺路径、特殊要求、强度要求 是否一致，不一致则报错
		int i=0;
		int Spec_Cnt = 0;
		for(PlnProdorder pldm:lpldm){
			PlnProdorder pp=new PlnProdorder();
			pp.setProd_order_no(pldm.getProd_order_no());
			//是否带状态
			List<PlnProdorder> lppc=this.getMapper(PlnProdorderMapper.class).findWithCondition(pp, " status>'0PAA10' ", "", 0, 0);
			if(lppc==null||lppc.size()==0){
				rm.setState("500");
				rm.setMsgInfo("生产订单不存在！");
				return rm;
			}
			pldm.setOrder_no(lppc.get(0).getOrder_no());
			pldm.setDiameter_inn_max(lppc.get(0).getDiameter_inn_max());//内径上限
			pldm.setDiameter_inn_min(lppc.get(0).getDiameter_inn_min());
			pldm.setDiameter_out_max(lppc.get(0).getDiameter_out_max());//外径
			pldm.setDiameter_out_min(lppc.get(0).getDiameter_out_min());
			pldm.setSingle_weight_min(lppc.get(0).getSingle_length_min());
			pldm.setSingle_weight_max(lppc.get(0).getSingle_length_max());
			pldm.setThick(lppc.get(0).getThick());
			pldm.setSteel_code(lppc.get(0).getSteel_code());
			pldm.setMin_single_wgt(lppc.get(0).getMin_single_wgt());//GetWeightByWth(pldm.getDiameter_inn_min(),pldm.getDiameter_out_min(),pldm.getSingle_weight_min()));
			pldm.setMax_single_wgt(lppc.get(0).getMax_single_wgt());//GetWeightByWth(pldm.getDiameter_inn_max(),pldm.getDiameter_out_max(),pldm.getSingle_weight_max()));
			pldm.setWidth(lppc.get(0).getWidth());
			pldm.setWidth_min(lppc.get(0).getWidth_min());
			pldm.setWidth_max(lppc.get(0).getWidth_max());
			//获取 用户指定生产订单分条数
			Spec_Cnt+=pldm.getSpec_Sub_Cnt()==null?0:pldm.getSpec_Sub_Cnt();
			
			if(pldm.getWidth_min()==null){
				pldm.setWidth_min(pldm.getWidth());
			}
			if(pldm.getWidth_max()==null){
				pldm.setWidth_max(pldm.getWidth());
			}
			if(pldm.getSingle_weight_min()==null){
				pldm.setSingle_weight_min(pldm.getSingle_weight());
			}
			if(pldm.getSingle_weight_max()==null){
				pldm.setSingle_weight_max(pldm.getSingle_weight());
			}
			
			
			//判断 传入的待设计量> 对应生产订单的欠分条设计成品量, 如果成立则报错
			pos.setProd_order_no(pldm.getProd_order_no());
			List<PlnProdorderStatistic> lpos=this.getMapper(PlnProdorderStatisticMapper.class).find(pos, 0, 0);
			if(pldm.getUndesign_wgt()>lpos.get(0).getLw_undsn()){
				rm.setState("500");
				rm.setMsgInfo("生产订单["+pldm.getProd_order_no()+"]填入的待设计量大于可设计量，不能设计！");
				return rm;
			}
			
			
			//否则获取 工艺路径(调用 质量模块接口)、特殊要求(调用 质量模块接口)、强度要求(调用 质量模块接口) 
			//填充pldm的里这几个字段值
			
			//判断当前数据跟第一条是否厚度、牌号
			if(i>0){
				if(!lpldm.get(0).getThick().equals(pldm.getThick())){
					rm.setState("500");
					rm.setMsgInfo("订单的厚度不一样，不能合卷分条!");
					return rm;
				}
				if(!lpldm.get(0).getSteel_code().equals(pldm.getSteel_code())){
					rm.setState("500");
					rm.setMsgInfo("订单的牌号不一样，不能合卷分条!");
					return rm;
				}
				//后续还有 工艺路径、特殊要求、强度要求
			}
			i++;
		}
		//读取基础配置 产线机组限制表；读取机组要求 内径限制值、外径限制值、
		//最大钢卷重量、原料宽度限制值、成品宽度限制值
		//按各订单厚度、强度要求，读取允许的最大分条数
		//读取基础配置 宽度晋级值(WIDTH_RISE)、外径晋级值(OUTTER_RISE)
		//************将读取到的数据赋值给 ClsRestrict**********************
		
		ArrayList param =null;
		All_Schemes.clear();
		try {
			double Spec_Inner_diam=(oci.getMemo1()==null?0:("".equals(oci.getMemo1().trim())?0:Double.parseDouble(oci.getMemo1())))
					,Spec_Outter_diam=(oci.getMemo2()==null?0:("".equals(oci.getMemo2().trim())?0:Double.parseDouble(oci.getMemo2())))
					,Spec_Width=(oci.getMemo3()==null?0:("".equals(oci.getMemo3().trim())?0:Double.parseDouble(oci.getMemo3())));
			//param=Init_Calc(TestDb());
			param = Init_Calc(lpldm,Spec_Cnt,Spec_Inner_diam,Spec_Outter_diam,Spec_Width);
		} catch (Exception e) {
			e.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo(e.getMessage());
			return rm;
		}
		try{
			//List<clsScheme> scheme = new ArrayList<clsScheme>();
			//定义开启10个线程
			int thread_num=10;
			CountDownLatch latch=new CountDownLatch(thread_num);
			//List<PlnProdorder> orders, ArrayList param,int thread_serial, int total_thread_serial
	        
			//循环启动各线程			
            for (int idx = 1; idx <= thread_num; idx++)	{
            	Worker works=new Worker(MachineRestrict, latch,lpldm,param,idx,thread_num); 
            	//Worker works=new Worker(MachineRestrict, latch,TestDb(),param,idx,thread_num); 
            	works.start();
            	//将结果写入到需返回的里面		
            }
	        
	        
	        latch.await();//等待所有线程完成工作  
			
			//Calc(lpldm, param, 1, 1);
			if(All_Schemes==null||All_Schemes.size()==0){
				rm.setState("500");
				rm.setMsgInfo("没有找到合适的设计方案！");
				return rm;
			}else{
				rm.setState("200");
				rm.setData(All_Schemes);
			}
		}catch(Exception ex){
			rm.setState("500");
			rm.setMsgInfo("设计失败");
			rm.setErrorInfo(ex.getMessage());
		}
		return rm;
	}

	
	private List<PlnProdorder> TestDb(){
		List<PlnProdorder> lpp=new ArrayList<PlnProdorder>();
		PlnProdorder pp=new PlnProdorder();
		pp.setThick(3d);
		pp.setUndesign_wgt(500000);
		pp.setLim_max_total_wgt(550000);
		pp.setDiameter_inn_min(508d);
		pp.setDiameter_inn_max(508d);
		pp.setDiameter_out_min(1400d);
		pp.setDiameter_out_max(2000d);
		pp.setWidth_min(63d);
		pp.setWidth_max(77d);
		pp.setMin_single_wgt(GetWeightByWth(508,1400,63));
		pp.setMax_single_wgt(GetWeightByWth(508,2000,77));
		lpp.add(pp);
		
		PlnProdorder pp2=new PlnProdorder();
		pp2.setThick(3d);
		pp2.setUndesign_wgt(200000);
		pp2.setLim_max_total_wgt(220000);
		pp2.setDiameter_inn_min(508d);
		pp2.setDiameter_inn_max(508d);
		pp2.setDiameter_out_min(1400d);
		pp2.setDiameter_out_max(1700d);
		pp2.setWidth_min(65d);
		pp2.setWidth_max(70d);
		pp2.setMin_single_wgt(GetWeightByWth(508,1400,65));
		pp2.setMax_single_wgt(GetWeightByWth(508,1700,70));
		lpp.add(pp2);
		
		PlnProdorder pp1=new PlnProdorder();
		pp1.setThick(3d);
		pp1.setUndesign_wgt(1000000);
		pp1.setLim_max_total_wgt(1100000);
		pp1.setDiameter_inn_min(508d);
		pp1.setDiameter_inn_max(508d);
		pp1.setDiameter_out_min(1300d);
		pp1.setDiameter_out_max(1500d);
		pp1.setWidth_min(65d);
		pp1.setWidth_max(77d);
		pp1.setMin_single_wgt(GetWeightByWth(508,1400,65));
		pp1.setMax_single_wgt(GetWeightByWth(508,1500,77));
		lpp.add(pp1);
		
		return lpp;
	}
	
	/**
	 * 根据产线获取产线的规格参数
	 * @param thick 厚度度
	 * */
	public List<ComDsnPltlmt> getMachineRestrictDb(Double thick){
		ComDsnPltlmt cdp=new ComDsnPltlmt();
		cdp.setPlt("Y1");//工厂
		cdp.setPlt_line("Y1");//产线
		List<ComDsnPltlmt> lcdp=this.getMapper(ComDsnPltlmtMapper.class).find(cdp, 0, 0);
		
		//最大分条数 
		List<ComDsnCutstd> lcdc=this.getMapper(ComDsnCutstdMapper.class).findWithCondition(null, " limit1_min<="+thick+" and limit1_max>="+thick, "", 0, 0);
		cdp.setApply_item("lim_max_split");
		cdp.setMin(lcdc.get(0).getValue1());
		lcdp.add(cdp);
		
		
		return lcdp;
	}
	
	private ArrayList Init_Calc(List<PlnProdorder> lpp, int spec_Cnt, double spec_Inner_diam, double spec_Outter_diam, double spec_Width) throws Exception{
		ArrayList Param=new ArrayList();
		
		ArrayList v_tmp_inners = new ArrayList();
        ArrayList v_inners = new ArrayList();
        double Total_Undesigned = 0;
        
        double sup_inner = 99999;//内径上限
        double inf_inner = 0;//内径下限
        double sup_outter = 99999;//外径上限
        double inf_outter = 0;//外径下限
        
        //指定原料卷 内外径和宽度
        double Spec_Inner_diam = spec_Inner_diam;
        double Spec_Outter_diam = spec_Outter_diam;
        double Spec_Width = spec_Width;
       
        
        //************后续这里应该丢下面的循环里面去***************
        try{
	        //根据产线获取产线的规格参数
	        List<ComDsnPltlmt> lc=getMachineRestrictDb(lpp.get(0).getThick());
	        MachineRestrict=new ClsRestrict(lc);
        }catch(Exception ex){
        	ex.printStackTrace();
        	throw new Exception("获取产线基础信息失败！");
        }
        
        if(spec_Cnt>MachineRestrict.lim_max_split){
         	throw new Exception("指定的各分条数之和[" + spec_Cnt + "] 大于设备限制[" + MachineRestrict.lim_max_split + "]");
        } 
        
        if (Spec_Inner_diam > 0 && (Spec_Inner_diam > MachineRestrict.lim_max_inner || Spec_Inner_diam < MachineRestrict.lim_min_inner)){
        	throw new Exception("指定的原料卷内径[" + Spec_Inner_diam + "]超出设备限制[" + MachineRestrict.lim_min_inner + "," + MachineRestrict.lim_max_inner + "]");
        }else if (Spec_Outter_diam > 0 && (Spec_Outter_diam > MachineRestrict.lim_max_outter || Spec_Outter_diam < MachineRestrict.lim_min_outter)){
        	throw new Exception("指定的原料卷外径[" + Spec_Outter_diam + "mm]超出设备限制[" + MachineRestrict.lim_min_outter + "," + MachineRestrict.lim_max_outter + "]");
        }else if (Spec_Width > 0 && (Spec_Width < MachineRestrict.lim_min_wdt || Spec_Width > MachineRestrict.lim_max_wdt)){
        	throw new Exception("指定的原料卷宽度[" + Spec_Width + "mm]超出设备限制[" + MachineRestrict.lim_min_wdt + "," + MachineRestrict.lim_max_wdt + "]");
        }
        	
        
        
		for(PlnProdorder pp:lpp){
			double dia_inn_min=pp.getDiameter_inn_min()==null?MachineRestrict.lim_min_inner:pp.getDiameter_inn_min();
			double dia_inn_max=pp.getDiameter_inn_max()==null?MachineRestrict.lim_min_inner:pp.getDiameter_inn_max();
				
			//内径下限最大值  
			inf_inner = Math.max(dia_inn_min, inf_inner);
            //内径上限最小值
			sup_inner = Math.min(dia_inn_max, sup_inner);
            //外径
			inf_outter = Math.max((pp.getDiameter_out_min()==null?MachineRestrict.lim_min_outter:pp.getDiameter_out_min()), inf_outter);
            sup_outter = Math.min((pp.getDiameter_out_max()==null?MachineRestrict.lim_max_outter:pp.getDiameter_out_max()), sup_outter);

            if (!v_tmp_inners.contains(dia_inn_min)){
            	v_tmp_inners.add(dia_inn_min);
            }
            if (!v_tmp_inners.contains(dia_inn_max)){
            	v_tmp_inners.add(dia_inn_max);
            }

            Total_Undesigned += pp.getUndesign_wgt();
            if (pp.getThick() < MachineRestrict.lim_min_height || pp.getThick() > MachineRestrict.lim_max_height){
                 throw new Exception("厚度超出机器限制范围！");
            }
		}
        
        
		if (sup_inner < inf_inner){
            throw new Exception("订单内径限制范围不匹配！");
        }
        else if (sup_outter < inf_outter){
            throw new Exception("订单外径限制范围不匹配！");
        }

        inf_inner = Math.max(inf_inner, MachineRestrict.lim_min_inner);
        sup_inner = Math.min(sup_inner, MachineRestrict.lim_max_inner);
        inf_outter = Math.max(inf_outter, MachineRestrict.lim_min_outter);
        sup_outter = Math.min(sup_outter, MachineRestrict.lim_max_outter);

        if (sup_inner < inf_inner){
            throw new Exception("订单内径限制超出机组范围！");
        }
        else if (sup_outter < inf_outter){
            throw new Exception("订单外径限制超出机组范围！");
        }

        for (int idx = v_tmp_inners.size() - 1; idx >= 0; idx--){
            if ((Double)v_tmp_inners.get(idx) >= inf_inner && (Double)v_tmp_inners.get(idx) <= sup_inner)
            {
                v_inners.add(v_tmp_inners.get(idx));
            }
        }
        
        if (Spec_Inner_diam > 0){
        	v_inners.clear();
        	v_inners.add(Spec_Inner_diam);
        	inf_inner = Spec_Inner_diam;
        	sup_inner = Spec_Inner_diam;
        }
        if (Spec_Outter_diam > 0){
        	inf_outter = Spec_Outter_diam;
        	sup_outter = Spec_Outter_diam;
        }
        

        Param.add(Total_Undesigned);
        Param.add(v_inners);
        Param.add(inf_inner);
        Param.add(sup_inner);
        Param.add(inf_outter);
        Param.add(sup_outter);
        Param.add(Spec_Width);
        
        return Param;
	}


	private static double GetWidthByWgt(double inner, double outter, double weight){
        return weight / (Math.PI * (Math.pow(outter / 2, 2) - Math.pow(inner / 2, 2)) * 7.85 * Math.pow(10, -6));
	} 
	
	private static double GetWeightByWth(double inner, double outter, double width){
         return Math.PI * (Math.pow(outter / 2, 2) - Math.pow(inner / 2, 2)) * width * 7.85 * Math.pow(10, -6);
	}
	
    
	//根据新评分值，剔除最小方案
    private static boolean AbundonLastSchemes(double v_score, List<clsScheme> Schemes){
        if (Schemes == null || Schemes.size() < MaxScheme) return true;
        
        double min_score = 99999;
        clsScheme min_scheme = null;

        //找最小评估值的方案
        for(clsScheme scheme : Schemes){
            if (scheme.score < min_score){
                min_score = scheme.score;
                min_scheme = scheme;
            }
        }

        if (v_score > min_score && min_scheme != null){
            Schemes.remove(min_scheme);
            return true;
        }
        return false;
    }
     /**
      * 多线程处理
      * */
    private static Semaphore semaphore = new Semaphore(1);

    static class Worker extends Thread{  
    	 ClsRestrict MachineRestrict;
    	 CountDownLatch latch;  
    	 List<PlnProdorder> orders; 
    	 ArrayList param;
    	 int thread_serial,total_thread_serial;
    	 
    	 public Worker(ClsRestrict MachineRestrict ,CountDownLatch latch,List<PlnProdorder> orders, ArrayList param,int thread_serial, int total_thread_serial){  
              this.MachineRestrict=MachineRestrict;  
              this.latch=latch;  
              this.orders=orders;
              this.param=param;
              this.thread_serial=thread_serial;
              this.total_thread_serial=total_thread_serial;
         }  
         public void run(){  
             System.out.println("================do work begin===============");  
             List<clsScheme> lcs=Calc();//工作了
             if(lcs!=null&&lcs.size()>0){
            	 try {
					semaphore.acquire();
					for(clsScheme cs:lcs){
	            		 if (!AbundonLastSchemes(cs.score, All_Schemes)) continue;
	            		 All_Schemes.add(cs);
	            	 }
            	 } catch (InterruptedException e) {
					e.printStackTrace();
				}finally{
					 semaphore.release();
				}
             }
             System.out.println("===========do work complete=================");  
             latch.countDown();//完成工作，计数器减一  
             
             /*try {  
	             Thread.sleep(workTime);  
	         } catch (InterruptedException e) {  
	             e.printStackTrace();  
	         }  */
         }  
               
         
         //开始计算， 传入订单信息, 参数信息， 当前线程序号(1,2,3 用于分配计算范围),  总线程数。        传出方案信息； 
     	 //List<PlnProdorder> orders, ArrayList param,int thread_serial, int total_thread_serial
         private List<clsScheme> Calc() {
     		double Total_Undesigned = (Double)param.get(0);
             ArrayList v_inners = (ArrayList)param.get(1);
             double inf_inner = (Double)param.get(2);
             double sup_inner = (Double)param.get(3);
             double inf_outter = (Double)param.get(4);
             double sup_outter = (Double)param.get(5);
             double Spec_Width = (Double)param.get(6);

             List<clsScheme> Schemes = new ArrayList<clsScheme>();
             double MaxScore = 0;

             int design_id = 0;

             double v_cut_wgt = 0;

             //根据线程值，计算外径循环范围
             double outter_Min = inf_outter + (thread_serial - 1) * (sup_outter - inf_outter) / total_thread_serial;
             double outter_Max = inf_outter + (thread_serial) * (sup_outter - inf_outter) / total_thread_serial;

             //根据晋级值修约到相应范围。
             outter_Min = Math.floor(outter_Min / MachineRestrict.outter_rise) * MachineRestrict.outter_rise;
             outter_Max = Math.ceil(outter_Max / MachineRestrict.outter_rise) * MachineRestrict.outter_rise;

             for (int idx1 = 0; idx1 < v_inners.size(); idx1++)
             {
                 double v_内径 = (Double)(v_inners.get(idx1));

                 for (double v_外径 = outter_Max; v_外径 >= outter_Min; v_外径 -= MachineRestrict.outter_rise)
                 { 
                     boolean continue_forOrder = false;
                     int orders_Count = orders.size();
                     double sup_wth_min = 0;
                     double inf_wth_max = 0;
                     

                     ArrayList Wdt_Cursor = new ArrayList();

                     //预留边重量
                     v_cut_wgt = GetWeightByWth(v_内径, v_外径, MachineRestrict.Cut_Reserve * 2);
                     //根据指定原料卷宽度，计算原料卷总量
                     double Coil_MaxWgt = 0;
                     if (Spec_Width > 0){
                    	 Coil_MaxWgt = GetWeightByWth(v_内径, v_外径, Spec_Width);
                    	 Coil_MaxWgt = Coil_MaxWgt > MachineRestrict.lim_max_wgt? MachineRestrict.lim_max_wgt: Coil_MaxWgt;
                     }else{
                    	 Coil_MaxWgt = MachineRestrict.lim_max_wgt;
                     }
                     
                     //除预留边外的 单卷最大重量。  如果设计重量要小于此重量，以设计重量为准。
                     double single_wgt = Math.min(Total_Undesigned,Coil_MaxWgt - v_cut_wgt);

                     List<clsOrderDsn> orders_dsn = new ArrayList<clsOrderDsn>();
                     
                     for(PlnProdorder order:orders){
                         double v_wth_min = 0.0;
                         double v_wth_max = 9999.0;
                    	 
                         clsOrderDsn ord_dsn = new clsOrderDsn();

                         //通过订单单重要求 ，计算宽度范围。 （注意，如果没有单重范围要求，则用单重计算）
                         if(order.getMin_single_wgt()>0){
                        	 v_wth_min = GetWidthByWgt(v_内径, v_外径, order.getMin_single_wgt());
                         }
                         if(order.getMax_single_wgt()>0){
                        	 v_wth_max = GetWidthByWgt(v_内径, v_外径, order.getMax_single_wgt());
                         }
                         //根据订单宽度范围，计算公共范围
                         v_wth_min = Math.max(v_wth_min,
                             Math.ceil(order.getWidth_min() / MachineRestrict.width_rise) * MachineRestrict.width_rise);
                         v_wth_max = Math.min(v_wth_max,
                             Math.floor(order.getWidth_max() / MachineRestrict.width_rise) * MachineRestrict.width_rise);

                         //根据宽度晋级值，修正到最近的范围。(避免订单要求出现小数，等其他情况。  统一按设备要求来)
                         v_wth_min = Math.ceil(v_wth_min / MachineRestrict.width_rise) * MachineRestrict.width_rise;
                         v_wth_max = Math.floor(v_wth_max / MachineRestrict.width_rise) * MachineRestrict.width_rise;

                         //判断宽度范围，是否在设备成品宽度要求范围内
                         if (v_wth_min > v_wth_max || v_wth_min > MachineRestrict.lim_max_wdt ||
                             v_wth_min > MachineRestrict.lim_max_sub_wdt || v_wth_max < MachineRestrict.lim_min_sub_wdt)
                         {
                             continue_forOrder = true;
                             orders_dsn.add(ord_dsn);
                             break;
                         }


                         ord_dsn.min_final_wdt = v_wth_min;
                         ord_dsn.max_final_wdt = v_wth_max;
                         ord_dsn.final_inner = v_内径;
                         ord_dsn.final_outter = v_外径;
                         ord_dsn.final_designed = true;
                         orders_dsn.add(ord_dsn);
                     }

                     if (!continue_forOrder)
                     {
                         for(clsOrderDsn ord_dsn : orders_dsn)
                         {
                             if (!ord_dsn.final_designed)
                             {
                                 continue_forOrder = true;
                                 break;
                             }
                         }
                     } 

                     if (continue_forOrder) continue;

                     //计算单卷内  各订单可安排的子卷数目范围
                     for (int i = 0; i < orders.size(); i++)
                     {
                     	PlnProdorder order = (PlnProdorder)orders.get(i);
                         clsOrderDsn ord_dsn = (clsOrderDsn)orders_dsn.get(i);

                         double total_wth_inAcoil;
                         double total_wgt_inAcoil;
                         total_wgt_inAcoil = single_wgt * order.getUndesign_wgt() / Total_Undesigned;
                         total_wth_inAcoil = GetWidthByWgt(ord_dsn.final_inner,
                            ord_dsn.final_outter, total_wgt_inAcoil);

                         ord_dsn.subCoil_cnt_Max = (int)Math.ceil(total_wth_inAcoil / ord_dsn.min_final_wdt) + 3;
                         ord_dsn.subCoil_cnt_Min = (int)Math.floor(total_wth_inAcoil * 0.7 / ord_dsn.max_final_wdt) - 3;

                         //使用总条数限制，进行修正。
                         int Estimate_subCoil_cnt = (int)Math.floor(MachineRestrict.lim_max_split * order.getUndesign_wgt() / Total_Undesigned)-3;
                         ord_dsn.subCoil_cnt_Min = ord_dsn.subCoil_cnt_Min > Estimate_subCoil_cnt ? Estimate_subCoil_cnt : ord_dsn.subCoil_cnt_Min;

                         
                         if (ord_dsn.subCoil_cnt_Min > MachineRestrict.lim_max_split) ord_dsn.subCoil_cnt_Min = MachineRestrict.lim_max_split -(orders.size() - 1)-3;
                         if (ord_dsn.subCoil_cnt_Max > MachineRestrict.lim_max_split) ord_dsn.subCoil_cnt_Max = MachineRestrict.lim_max_split;
                         if (ord_dsn.subCoil_cnt_Min <= 0) ord_dsn.subCoil_cnt_Min = 1;
                         if (ord_dsn.subCoil_cnt_Max <= 0) ord_dsn.subCoil_cnt_Max = 1;
                         
                         //使用生产订单指定条数 进行修正。
                         if (order.getSpec_Sub_Cnt()!=null&& order.getSpec_Sub_Cnt()> 0){
                        	 ord_dsn.subCoil_cnt_Min = order.getSpec_Sub_Cnt();
                        	 ord_dsn.subCoil_cnt_Max = order.getSpec_Sub_Cnt();
                         }
                         
                         
                         //循环各订单宽度用的指示器， 默认从各订单最小宽度开始
                         Wdt_Cursor.add(ord_dsn.min_final_wdt);
                     }

                     int Split_Cnt = 0;
                     double Total_CutLoss = 0;
                     double CoilNetWidth = 0;
                     double CoilGrossWidth = 0;
                     double CoilGrossWeight = 0;

                     boolean continue_forNextWdt = false;
                     //遍历各订单宽度
                     while (true)
                     {
                         //订单宽度遍历 递增指针
                         if (continue_forNextWdt)
                         {
                             for (int idx = 0; idx < orders_Count; idx++)
                             {
                                 if (idx != orders_Count - 1 && (Double)(Wdt_Cursor.get(idx)) + MachineRestrict.width_rise > ((clsOrderDsn)orders_dsn.get(idx)).max_final_wdt)
                                 {
                                     Wdt_Cursor.set(idx, ((clsOrderDsn)orders_dsn.get(idx)).min_final_wdt);
                                     continue;
                                 }
                                 else
                                 {
                                     Wdt_Cursor.set(idx, (Double)Wdt_Cursor.get(idx) + MachineRestrict.width_rise);//晋级值递增
                                     break;
                                 }
                             }
                         }
                         continue_forNextWdt = true;

                         //循环完成，退出
                         if ((Double)Wdt_Cursor.get(orders_Count - 1) > ((clsOrderDsn)orders_dsn.get(orders_Count - 1)).max_final_wdt) break;
                          

                         //初始化数量循环变量
                         boolean continue_forNextQty = false;
                         ArrayList Qty_Cursor = new ArrayList();
                         for (int idx = 0; idx < orders_Count; idx++)
                         {
                             clsOrderDsn ord_dsn = (clsOrderDsn)orders_dsn.get(idx);
                             //循环各订单子卷数用的指示器， 默认从各订单最小数量开始
                             Qty_Cursor.add(ord_dsn.subCoil_cnt_Min);
                         }


                         //遍历各订单数量
                         while (true)
                         {
                             //订单子卷数 递增遍历
                             if (continue_forNextQty)
                             {
                                 for (int idx = 0; idx < orders_Count; idx++)
                                 {
                                     if (idx != orders_Count - 1 && (Integer)(Qty_Cursor.get(idx)) + 1 > ((clsOrderDsn)orders_dsn.get(idx)).subCoil_cnt_Max)
                                     {
                                         Qty_Cursor.set(idx, ((clsOrderDsn)orders_dsn.get(idx)).subCoil_cnt_Min);
                                         continue;
                                     }
                                     else
                                     {
                                         Qty_Cursor.set(idx, (Integer)Qty_Cursor.get(idx) + 1);
                                         break;
                                     }
                                 }
                             }

                             if ((Integer)Qty_Cursor.get(orders_Count - 1) >
                                 ((clsOrderDsn)orders_dsn.get(orders_Count - 1)).subCoil_cnt_Max)
                                 break;

                             continue_forNextQty = true;


                             //正式逻辑


                             boolean continue_Next = false;

                             Split_Cnt = 0; ; //总分条数
                             Total_CutLoss = 0; //总切损
                             CoilNetWidth = 0; //净宽度
                             CoilGrossWidth = 0;//毛宽度
                             CoilGrossWeight = 0; //毛重

                             for (int idx = 0; idx < orders_Count; idx++)
                             {
                             	PlnProdorder order = orders.get(idx);
                                 clsOrderDsn ord_dsn = orders_dsn.get(idx);

                                 ord_dsn.final_subCoil_cnt = (Integer)Qty_Cursor.get(idx);
                                 ord_dsn.final_width = (Double)Wdt_Cursor.get(idx);

                                 //判断 宽度是否符合设备限制
                                 if (ord_dsn.final_width > MachineRestrict.lim_max_sub_wdt ||
                                     ord_dsn.final_width < MachineRestrict.lim_min_sub_wdt)
                                 {
                                     continue_Next = true;
                                     break;
                                 }

                                 ord_dsn.final_wgt = GetWeightByWth(ord_dsn.final_inner, ord_dsn.final_outter, ord_dsn.final_width);

                                 CoilNetWidth += ord_dsn.final_subCoil_cnt * ord_dsn.final_width;
                                 Split_Cnt += (Integer)Qty_Cursor.get(idx);

                             }

                             if (continue_Next) continue;

                             //判断条数是否超机器限制
                             if (Split_Cnt > MachineRestrict.lim_max_split) continue;

                             //判断母卷宽度是否超机器限制
                             Total_CutLoss = (Split_Cnt - 1) * MachineRestrict.Cut_Loss;
                             CoilGrossWidth = CoilNetWidth + MachineRestrict.Cut_Reserve * 2 + Total_CutLoss;

                             if (CoilGrossWidth > MachineRestrict.lim_max_wdt || CoilGrossWidth < MachineRestrict.lim_min_wdt) continue;


                             CoilGrossWeight = GetWeightByWth(v_内径, v_外径, CoilGrossWidth);
                             if (CoilGrossWeight > MachineRestrict.lim_max_wgt) continue;

                             //计算 母卷 总卷数
                             int mat_coil_cnt = 99999;
                             
                             for (int idx = 0; idx < orders_Count; idx++)
                             {
                             	PlnProdorder order = orders.get(idx);
                                 clsOrderDsn ord_dsn = orders_dsn.get(idx);
                                 
                                 int coil_cnt =
                                     (int)Math.floor(order.getUndesign_wgt() / GetWeightByWth(ord_dsn.final_inner, ord_dsn.final_outter, ord_dsn.final_width * ord_dsn.final_subCoil_cnt));
                                 mat_coil_cnt = mat_coil_cnt > coil_cnt ? coil_cnt : mat_coil_cnt;
                                 
                               ord_dsn.weight_in_Acoil= GetWeightByWth(v_内径, v_外径, CoilNetWidth ); 
                             }
                             mat_coil_cnt = mat_coil_cnt < 1 ? 1 : mat_coil_cnt;


                             //评估方案

                             //-- 偏差率
                             double v_deviation=0;
                             double v_deviation_1=0;
                             
/*                             for (int idx = 0; idx < orders_Count; idx++)
                             {PlnProdorder order = orders.get(idx);
                             clsOrderDsn ord_dsn = orders_dsn.get(idx);
                             v_deviation+=  Math.abs( ord_dsn.weight_in_Acoil*mat_coil_cnt-order.getUndesign_wgt());
                             v_deviation_1+=  Math.abs( ord_dsn.weight_in_Acoil*(mat_coil_cnt+1)-order.getUndesign_wgt());

                             }
                              v_deviation =(v_deviation) / Total_Undesigned;
                              v_deviation_1 =(v_deviation_1) / Total_Undesigned;
*/
                             
                             v_deviation = (GetWeightByWth(v_内径, v_外径, CoilNetWidth) * mat_coil_cnt - Total_Undesigned) / Total_Undesigned;
                             v_deviation_1 = (GetWeightByWth(v_内径, v_外径, CoilNetWidth) * (mat_coil_cnt + 1) - Total_Undesigned) / Total_Undesigned;
                             
                             
                             v_deviation = Math.abs(v_deviation);
                             v_deviation_1 = Math.abs(v_deviation_1);
                             if (v_deviation_1 < v_deviation){
                            	 v_deviation = v_deviation_1;
                            	 mat_coil_cnt += 1;
                             }
                             
                             //计算评估值
                             double v_last_score = 0.7 * CoilNetWidth / CoilGrossWidth + 0.3 * (1 - v_deviation);

                             //排除最小方案
                             if (!AbundonLastSchemes(v_last_score, Schemes)) continue;

                             //新增方案
                             design_id++;
                             clsScheme dr_main = new clsScheme();
                             dr_main.setDesign_no(design_id);
                             dr_main.setDeviation(v_deviation);
                             dr_main.setCoil_cnt(mat_coil_cnt);
                             dr_main.setInner_diam(v_内径);
                             dr_main.setOutter_diam(v_外径);

                             double Total_Design_Weight = 0;
                             double Remain_undesign_wgt = 0;

                             String cut_style = "";
                             List<clsSchemeDetail> details=new ArrayList<clsSchemeDetail>();
                             for (int idx = 0; idx < orders_Count; idx++){
                             	PlnProdorder order = orders.get(idx);
                                 clsOrderDsn ord_dsn = orders_dsn.get(idx);

                                 ord_dsn.Total_Design_Weight = ord_dsn.final_wgt * ord_dsn.final_subCoil_cnt * mat_coil_cnt;

                                 clsSchemeDetail dr_detail = new clsSchemeDetail();

                                 dr_detail.setDesign_no(design_id);
                                 dr_detail.setOrder_no(order.getProd_order_no());
                                 dr_detail.setWidth(ord_dsn.final_width);
                                 dr_detail.setSub_coil_cnt(ord_dsn.final_subCoil_cnt);
                                 dr_detail.setWeight(ord_dsn.final_wgt);
                                 dr_detail.setUndesign_wgt(order.getUndesign_wgt());
                                 dr_detail.setRemain_undesign_wgt(order.getUndesign_wgt() - ord_dsn.Total_Design_Weight);
                                 dr_detail.setTotal_Design_Weight(ord_dsn.Total_Design_Weight);

                                 Remain_undesign_wgt += order.getUndesign_wgt() - ord_dsn.Total_Design_Weight;
                                 Total_Design_Weight += ord_dsn.Total_Design_Weight;

                                 cut_style += ord_dsn.final_subCoil_cnt+"*"+ord_dsn.final_width+"+";
                                 
                                 details.add(dr_detail);
                             }
                             dr_main.setDetails(details);
                             
                             cut_style = cut_style.substring(0, cut_style.length() - 1);

                             dr_main.setUndesign_wgt(Total_Undesigned);
                             dr_main.setRemain_undesign_wgt(Remain_undesign_wgt);
                             dr_main.setTotal_Design_Weight(Total_Design_Weight);
                             dr_main.setCut_style( cut_style);
                             dr_main.setBelt_cnt (Split_Cnt);
                             dr_main.setTimber_rate( CoilNetWidth / CoilGrossWidth);
                             dr_main.setScore(v_last_score);
                             dr_main.setWidth(CoilGrossWidth);
                             dr_main.setTotal_Cut_Loss(Total_CutLoss);
                             dr_main.setTotal_Cut_Reserve(2 * MachineRestrict.Cut_Reserve);
                             dr_main.setSingle_wgt(CoilGrossWeight);
                             dr_main.setCut_reserve(MachineRestrict.Cut_Reserve);
                             Schemes.add(dr_main);
                         }

                     }

                 }
             }

             return Schemes;
     	}
 
     	
     	
     }  
     
  //*************************************自动设计代码end*************************************
}
