package com.steering.pss.plnsaleord.GpOptimize;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import CoreFS.SA08.CoreXmlSqlParsersFactory;
import com.steering.pss.plnsaleord.GpOptimize.model.PlnReqinfGpEntity;
import com.steering.pss.plnsaleord.lenthCal.CoreIsRounded;
import com.steering.pss.plnsaleord.order.baseMethod.CoreOrdBase;

/**
 * 管坯计算公共方法
 * 
 * @author TJG
 * @version v1.1
 * @date 2017.05.29
 */
public class CoreLenMsGp {
	/**
	 * 圆周率
	 */
	private static double Pi = 3.1415926; // 圆周率
	/**
	 * 密度p
	 */
	private static double P = 7.8;

	/**
	 * 计算过程(轧管前工序是铸造)
	 */
	public static boolean getZzCuttolen(Connection conn,
			PlnReqinfGpEntity gpReqEntity, String[] message,
			String zgPlineCode, String desginKey, String mscPline)
			throws SQLException {
		double zgGpSingle = Double.parseDouble(gpReqEntity.getLenGpSingle()); // 轧管单倍坯长
		double burning = 0; // 烧损(%)
		double zgDiameterGp = Double.parseDouble(gpReqEntity.getDiameterGp());// 轧管断面
		double zgwtSingle = CoreOrdBase.GpweightOfmi(zgDiameterGp); // 轧管坯米单重
		int numberRuler = 0;// 倍尺数
		double cutLenBurn = 0;// 倍尺坯分切长度损失（mm）
		double lengthmaxZg = 0; // 轧管最大长度
		double lengthminZg = 0; // 轧管最小长度
		double lengthmax = 0; // 前工序最大长度
		double lengthmin = 0; // 前工序最小长度
		double casLengMax = 0;// 坯子长度上限
		double casLengMin = 0;// 坯子长度下限

		// 轧管产线长度范围
		String sql = CoreXmlSqlParsersFactory
				.getSql("CorePlnZgMStoGp.selectBasePlineCode");
		PreparedStatement pst = conn.prepareStatement(sql);
		pst.setObject(1, zgPlineCode);
		ResultSet rst = pst.executeQuery();
		if (rst.next()) {
			lengthmaxZg = rst.getDouble("IN_MATERIAL_LEN_MAX");
			lengthminZg = rst.getDouble("IN_MATERIAL_LEN_MIN");
		}
		rst.close();
		pst.close();
		String messg = "";
		//TZH 制成没有C的铸造环节换成新的合同  24.9.15
		// 获取最佳铸造产线
//		sql = CoreXmlSqlParsersFactory
//				.getSql("CorePlnZgMStoGp.selectProcessBPline");
		sql = CoreXmlSqlParsersFactory
		.getSql("CorePlnZgMStoGp.selectProcessBPlineNEW");
	
		if (gpReqEntity.getIfbuyplan().equals("1")) {
			sql += " AND B.PLINE_CODE ='C063'";
			messg = "外购";
		} else {
			sql += " AND B.PLINE_CODE NOT IN ('C063')";
			messg = "自炼";
		}
		sql += " ) ORDER BY T.PLINE_LEVEL ASC, T.PLINE_CODE ASC";
		pst = conn.prepareStatement(sql);
		pst.setObject(1, gpReqEntity.getGradecode());
		pst.setObject(2, gpReqEntity.getMaterialNo());
//		pst.setObject(3, String.format("%.2f", zgDiameterGp));
//		pst.setObject(4, desginKey);
//		pst.setObject(5, mscPline);
		rst = pst.executeQuery();
		while (rst.next()) {
			lengthmax = rst.getDouble("LENGTH_MAX");
			lengthmin = rst.getDouble("LENGTH_MIN");

			// 前工序成品转移最长or轧管原料进厂最长，取二者最小
			if (lengthmax > lengthmaxZg) {
				casLengMax = lengthmaxZg;
			} else {
				casLengMax = lengthmax;
			}
			// 坯子长度下限：前工序成品转移最短or轧管原料进厂最短，取二者最大
			if (lengthmin > lengthminZg) {
				casLengMin = lengthmin;
			} else {
				casLengMin = lengthminZg;
			}
			// 最大长度必须大于零
			if (casLengMax <= 0) {
				message[0] = "坯子长度上限必须大于零。";
				return false;
			}

			// 最小长度必须大于等于零
			if (casLengMin < 0) {
				message[0] = "坯子长度下限必须大于等于零。";
				return false;
			}
			// x=int (坯子长度下限 / 单倍坯长)
			int x = (int) (casLengMin / (zgGpSingle / 1000));
			if (x * (zgGpSingle / 1000) < casLengMin) {
				x = x + 1;
			}
			int y = (int) (casLengMax / (zgGpSingle / 1000));
			int waseTim = 0;
			if (x > y) {
				waseTim = y;
			} else {
				// 获取最小整数
				int min = CoreIsRounded.isRounded(x, y);
				if (min != 0) {
					waseTim = min;
				}
			}
			if (gpReqEntity.getIfbuyplan().equals("0")) {
				if (zgPlineCode.equals("C008")) {// 轧管250
					if (rst.getString("PLINE_CODE") != null
							&& rst.getString("PLINE_CODE").equals("C002")) {// 一炼铸机
						numberRuler = waseTim;
						gpReqEntity.setPlineCodeZz(rst.getString("PLINE_CODE"));
						gpReqEntity.setPlineNameZz(rst.getString("PLINE_NAME"));
						if (rst.getString("BURNOUT_RATE") != null) {
							burning = rst.getDouble("BURNOUT_RATE") / 100;
						}
					}
					break;
				}
			}
			// 取最小倍尺数
			if (waseTim < numberRuler || numberRuler == 0) {
				numberRuler = waseTim;
				gpReqEntity.setPlineCodeZz(rst.getString("PLINE_CODE"));
				gpReqEntity.setPlineNameZz(rst.getString("PLINE_NAME"));
				if (rst.getString("BURNOUT_RATE") != null) {
					burning = rst.getDouble("BURNOUT_RATE") / 100;
				}
			}
			// 倍尺数为1 时调出循环
			if (numberRuler == 1) {
				break;
			}
		}
		rst.close();
		pst.close();
//TZH 24.9.14 注释 没有天津的数据  不用这个判断了  
//		if (gpReqEntity.getPlineCodeZz().equals("")) {
//			message[0] = "未找到" + messg + "铸造产线";
//			return false;
//		}
		// // 烧损率必须小于100%
		// if (burning >= 1 || burning < 0) {
		// message[0] = "烧损率必须在0-99%之间！。";
		// return false;
		// }
		// 2> 倍尺坯分切长度损失（mm） =（倍尺数-1）*10mm
		cutLenBurn = (numberRuler - 1) * 10;
		// 3> 倍尺坯长= 单倍坯长 * 倍尺数 + 倍尺坯分切长度损失
		double lenGpSingle = zgGpSingle * numberRuler;// + cutLenBurn
		// 4> 倍尺坯单支重=坯米单重*倍尺坯长/1000
		double wtGpSingle = zgwtSingle * (lenGpSingle / 1000);
		// 5> 倍尺需坯支= int (单倍坯支数 / 倍尺数+0.85)
		// double gpNumLong = (int)(Double.parseDouble(gpReqEntity.getGpNum())
		// / numberRuler + 0.85);
		int gpNumLong = 0;
		if (zgDiameterGp >= 310) {
			gpNumLong = (int) Math.ceil(Double.parseDouble(gpReqEntity
					.getGpWeightMin())
					/ wtGpSingle);
		} else {
			gpNumLong = (int) Math.ceil(Double.parseDouble(gpReqEntity
					.getGpWeight())
					/ wtGpSingle);
		}
		int gpNumMin = (int) Math.ceil(Double.parseDouble(gpReqEntity
				.getGpWeightMin())
				/ wtGpSingle);
		// 6> 倍尺需坯吨=倍尺需坯支*倍尺坯单支重
		double gpWtLong = gpNumLong * wtGpSingle;
		double gpWtLongMin = gpNumMin * wtGpSingle;
		gpReqEntity.setCutNumGp(String.valueOf(numberRuler));
		gpReqEntity.setCutLoseLen(String.valueOf(cutLenBurn));
		gpReqEntity.setLengthGp(String.valueOf(lenGpSingle));
		gpReqEntity.setGpNumLong(String.valueOf(gpNumLong));
		gpReqEntity.setGpWtLong(String.valueOf(intThe(gpWtLong)));
		gpReqEntity.setOutWtZz(String.valueOf(intThe(gpWtLong)));
		gpReqEntity.setOutNumZz(String.valueOf(gpNumLong));
		gpReqEntity.setWtOneZz(String.valueOf(intThe(wtGpSingle)));
		gpReqEntity.setDiameterZz(String
				.valueOf((int) Math.floor(zgDiameterGp)));
		gpReqEntity.setLengthZz(String.valueOf(lenGpSingle / 1000));
		gpReqEntity.setGpWeightMin(gpReqEntity.getGpWeightMin());
		gpReqEntity.setGpWtLongMin(String.valueOf(intThe(gpWtLongMin)));
		return true;
	}

	/**
	 * 获取连铸定尺
	 * 
	 * @param conn
	 * @param gpReqEntity
	 * @param message
	 * @return
	 * @throws SQLException
	 */
	public static boolean getCuttolen(Connection conn,
			PlnReqinfGpEntity gpReqEntity, String[] message,
			String zgPlineCode, String desginKey, String mscPline)
			throws SQLException {
		PreparedStatement ps = null;
		ResultSet rs = null;
		String sql = "";
		double wjJgallow = 20;// 锻坯外径加工余量=20mm
		double cutHeadEnd = 200;// 锻坯头尾切损长=200mm
		double buring = 0;// 锻造烧损(%)
		double zgDiameterGp = Double.parseDouble(gpReqEntity.getDiameterGp());// 轧管断面
		double zgGpSingle = Double.parseDouble(gpReqEntity.getLenGpSingle());// 轧管单倍坯长
		double zgwtSingle = CoreOrdBase.GpweightOfmi(zgDiameterGp); // 轧管坯米单重
		double wastDia = 400;// 默认 最佳断面
		int cutNum = 0;// 分切数
		int numAfterCut = Integer.parseInt(gpReqEntity.getGpNum());// 管坯切后支数（单倍坯支数）
		double cuttolength = 0;// 连铸坯定尺（m）
		double diameterZz = 400;// 连铸断面
		String specCodeZz = "";// 铸造规格代码
		String specNameZz = "";// 铸造规格
		String outMaterialNo = "";// 产出物料
		String outMaterialNm = "";// 产出物料
		double cutLenBurn = 0;// 倍尺坯分切长度损失（mm）

		//  锻造后外径：=轧管截面+锻坯外径加工余量
		double outDiameter = zgDiameterGp + wjJgallow;
		//  锻造后单倍坯长：=单倍坯长+锻坯头尾切损长
		double ZzSingle = zgGpSingle + cutHeadEnd;
		//  锻造后单倍坯重：=7.8*3.1415926* (轧管截面+锻坯外径加工余量)* (轧管截面+锻坯外径加工余量)/4 *
		// (单倍坯长+锻坯头尾切损长)/1000/1000/1000
		double dzSWtLong = 7.8 * Pi * outDiameter * (outDiameter / 4)
				* ZzSingle / 1000 / 1000 / 1000;

		gpReqEntity.setDzLoseAdd(String.valueOf(wjJgallow));
		gpReqEntity.setDzCutHeadEnd(String.valueOf(cutHeadEnd));

		// // 获取最佳断面
		// sql = CoreXmlSqlParsersFactory
		// .getSql("CorePlnZgMStoGp.getMscCastRForg");
		// sql += " AND TRIM(T.SPEC_CODE) IS NOT NULL"
		// + " AND S1.DIMATER IS NOT NULL";
		// ps = conn.prepareStatement(sql);
		// ps.setObject(1, zgDiameterGp);
		// rs = ps.executeQuery();
		// while (rs.next()) {
		// double wastDiaTemp = 0;
		// if (rs.getString("DIMATER") == null) {
		// continue;
		// }
		// diameterZz = Double.parseDouble(rs.getString("DIMATER"));
		// if (diameterZz < zgDiameterGp + wjJgallow) {
		// continue;
		// }
		// wastDiaTemp = diameterZz - zgDiameterGp - wjJgallow;
		// if (wastDia == 0 || wastDia > wastDiaTemp) {
		// wastDia = wastDiaTemp;// 最佳断面
		// // cuttolength = getCuttolength(blankSinGpWt, diameterZz,
		// // buring);
		// specCodeZz = rs.getString("SPEC_CODE");
		// if (rs.getString("SPEC_NAME") != null) {
		// specNameZz = rs.getString("SPEC_NAME");
		// }
		// }
		// }
		// rs.close();
		// ps.close();
		specCodeZz = "C005419";
		specNameZz = "400.00";
		// if (specCodeZz.equals("")) {
		// message[0] = "未找到合适连铸坯规格。";
		// return false;
		// }
		double lengthmaxZg = 0; // 轧管最大长度
		double lengthminZg = 0; // 轧管最小长度

		// 轧管产线长度范围
		sql = CoreXmlSqlParsersFactory
				.getSql("CorePlnZgMStoGp.selectBasePlineCode");
		PreparedStatement pst = conn.prepareStatement(sql);
		pst.setObject(1, zgPlineCode);
		ResultSet rst = pst.executeQuery();
		if (rst.next()) {
			lengthmaxZg = rst.getDouble("IN_MATERIAL_LEN_MAX");
			lengthminZg = rst.getDouble("IN_MATERIAL_LEN_MIN");
		}
		rst.close();
		pst.close();
		int numberRuler = 0;
		String messg = "";
		// 获取最佳铸造产线
		outMaterialNo = "PA" + specCodeZz + gpReqEntity.getGradecode();
		outMaterialNm = "PA" + specNameZz + "," + gpReqEntity.getGradename();
		sql = CoreXmlSqlParsersFactory
				.getSql("CorePlnZgMStoGp.selectProcessBPline");
		if (gpReqEntity.getIfbuyplan().equals("1")) {
			sql += " AND B.PLINE_CODE = 'C063'";
			messg = "外购";
		} else {
			sql += " AND B.PLINE_CODE NOT IN ('C063')";
			messg = "自炼";
		}
		sql += " ) ORDER BY T.PLINE_LEVEL ASC, T.PLINE_CODE ASC";
		pst = conn.prepareStatement(sql);
		pst.setObject(1, gpReqEntity.getGradecode());
		pst.setObject(2, outMaterialNo);
		pst.setObject(3, String.format("%.2f", zgDiameterGp));
		pst.setObject(4, desginKey);
		pst.setObject(5, mscPline);
		rst = pst.executeQuery();
		while (rst.next()) {
			double lengthmax = 0; // 前工序最大长度
			double lengthmin = 0; // 前工序最小长度
			double casLengMax = 0;// 坯子长度上限
			double casLengMin = 0;// 坯子长度下限
			lengthmax = rst.getDouble("LENGTH_MAX");
			lengthmin = rst.getDouble("LENGTH_MIN");

			// 前工序成品转移最长or轧管原料进厂最长，取二者最小
			if (lengthmax > lengthmaxZg) {
				casLengMax = lengthmaxZg;
			} else {
				casLengMax = lengthmax;
			}
			// 坯子长度下限：前工序成品转移最短or轧管原料进厂最短，取二者最大
			if (lengthmin > lengthminZg) {
				casLengMin = lengthmin;
			} else {
				casLengMin = lengthminZg;
			}
			// 最大长度必须大于零
			if (casLengMax <= 0) {
				message[0] = "坯子长度上限必须大于零。";
				return false;
			}

			// 最小长度必须大于等于零
			if (casLengMin < 0) {
				message[0] = "坯子长度下限必须大于等于零。";
				return false;
			}
			// x=int (坯子长度下限 / 单倍坯长)
			int x = (int) (casLengMin / (zgGpSingle / 1000));
			int y = (int) (casLengMax / (zgGpSingle / 1000));
			if (x * (zgGpSingle / 1000) < casLengMin) {
				x = x + 1;
			}
			int waseTim = 0;
			if (x > y) {
				waseTim = y;
			} else {
				// 获取最小整数
				int min = CoreIsRounded.isRounded(x, y);
				if (min != 0) {
					waseTim = min;
				}
			}
			if (gpReqEntity.getIfbuyplan().equals("0")) {
				if (zgPlineCode.equals("C008")) {// 轧管250
					if (rst.getString("PLINE_CODE") != null
							&& rst.getString("PLINE_CODE").equals("C002")) {// 一炼铸机
						numberRuler = waseTim;
						gpReqEntity.setPlineCodeZz(rst.getString("PLINE_CODE"));
						gpReqEntity.setPlineNameZz(rst.getString("PLINE_NAME"));
					}
					break;
				}
			}
			// 取最小倍尺数
			if (waseTim < numberRuler || numberRuler == 0) {
				numberRuler = waseTim;
				gpReqEntity.setPlineCodeZz(rst.getString("PLINE_CODE"));
				gpReqEntity.setPlineNameZz(rst.getString("PLINE_NAME"));
			}
			// 倍尺数为1 时调出循环
			if (numberRuler == 1) {
				break;
			}
		}
		rst.close();
		pst.close();
		if (gpReqEntity.getPlineCodeZz().equals("")) {
			message[0] = "未找到" + messg + "铸造产线。";
			return false;
		}

		gpReqEntity.setWlidZz(outMaterialNo);
		gpReqEntity.setWldescZz(outMaterialNm);

		// 获取最佳锻造产线
		sql = CoreXmlSqlParsersFactory
				.getSql("CorePlnZgMStoGp.selectProcessCPline");
		if (gpReqEntity.getIfbuyplan().equals("1")) {
			sql += " AND B.PLINE_CODE ='C064'";
		} else {
			sql += " AND B.PLINE_CODE NOT IN ('C064')";
		}
		sql += " ) ORDER BY T.PLINE_LEVEL ASC, T.PLINE_CODE ASC";
		ps = conn.prepareStatement(sql);
		ps.setObject(1, gpReqEntity.getWlidZz());
		ps.setObject(2, gpReqEntity.getMaterialNo());
		ps.setObject(3, desginKey);
		ps.setObject(4, mscPline);
		rs = ps.executeQuery();
		while (rs.next()) {
			int cutNumTemp = 0;
			double lenMax = 0;
			double lenMin = 0;
			lenMin = rs.getDouble("LENGTH_MIN") * 1000;
			lenMax = rs.getDouble("LENGTH_MAX") * 1000;
			cutNum = 2;
			// // cutNumTemp = getlenInRange(lenMax, lenMin, zgGpSingle);
			// if (cutNumTemp <= 0) {
			// continue;
			// }
			// if (cutNum < cutNumTemp || cutNum == 0) {
			// cutNum = cutNumTemp;
			buring = rs.getDouble("LENGTH_MAX");
			gpReqEntity.setDzBurnLose(String.valueOf(buring));
			gpReqEntity.setPlineCodeDz(rs.getString("PLINE_CODE"));
			gpReqEntity.setPlineNameDz(rs.getString("PLINE_NAME"));
			// }
		}
		rs.close();
		ps.close();
		if (gpReqEntity.getPlineCodeDz().equals("")) {
			message[0] = "未找" + messg + "锻造产线。";
			return false;
		}
		// 最佳原料米单重（连铸）
		double lzDiamWtM = CoreOrdBase.GpweightOfmi(diameterZz);
		// 倍尺坯分切长度损失（mm） =（倍尺数-1）*10mm
		cutLenBurn = (cutNum - 1) * 10;
		//  锻造后N倍坯长：=N*单倍坯长+锻坯头尾切损长+（N-1）*10mm
		double dzSingleN = 2 * zgGpSingle + cutLenBurn + cutHeadEnd;

		//  锻造后N倍坯重：=7.8*3.1415926* (轧管截面+锻坯外径加工余量)* (轧管截面+锻坯外径加工余量)/4 *
		// (N*单倍坯长+(N-1)*10+锻坯头尾切损长)/1000/1000/1000
		double dzSWtLongN = 7.8 * Pi * outDiameter * (outDiameter / 4)
				* dzSingleN / 1000 / 1000 / 1000;
		// 400单倍坯长=锻造2单倍坯重/（1-烧损）/原料断面的米单重
		double lzSingle = dzSWtLongN / (1 - buring / 100) / (lzDiamWtM / 1000);
		// 400单倍坯重
		double lzDiamWtSingle = dzSWtLongN / (1 - buring / 100);
		// 400的需坯支：轧管需坯支
		// double lzYlGpNum = (int) (numAfterCut / 2);
		int lzYlGpNum = 0;
		if (zgDiameterGp >= 310) {
			lzYlGpNum = (int) Math.ceil(Double.parseDouble(gpReqEntity
					.getGpWeightMin())
					/ lzDiamWtSingle);
		} else {
			lzYlGpNum = (int) Math.ceil(Double.parseDouble(gpReqEntity
					.getGpWeight())
					/ lzDiamWtSingle);
		}
		int lzYlGpNumMin = (int) Math.ceil(Double.parseDouble(gpReqEntity
				.getGpWeightMin())
				/ lzDiamWtSingle);
		// 400的需坯吨：400单倍坯重*轧管需坯支
		double lzYlGpWt = lzDiamWtSingle * lzYlGpNum;
		// int lzYlGpNumMin = (int) ((Double.parseDouble(gpReqEntity
		// .getGpWeightMin()) / Double.parseDouble(gpReqEntity
		// .getWeightGpOne()))) / 2;
		double lzYlGpWtMin = lzDiamWtSingle * lzYlGpNumMin;
		gpReqEntity.setCutNumGp(String.valueOf(cutNum));
		gpReqEntity.setWtOneZz(String.valueOf(intThe(lzDiamWtSingle)));
		gpReqEntity.setOutNumZz(String.valueOf(lzYlGpNum));
		gpReqEntity.setOutWtZz(String.valueOf(intThe(lzYlGpWt)));
		gpReqEntity.setCutLoseLen(String.valueOf(cutLenBurn));
		gpReqEntity.setLengthGp(String.valueOf(lzSingle));
		gpReqEntity.setGpNumLong(String.valueOf(lzYlGpNum));
		gpReqEntity.setGpWtLong(String.valueOf(intThe(lzYlGpWt)));
		gpReqEntity.setLengthZz(String.valueOf(lzSingle / 1000));
		gpReqEntity.setDiameterZz(String.valueOf((int) Math.floor(diameterZz)));
		gpReqEntity.setGpWeightMin(gpReqEntity.getGpWeightMin());
		gpReqEntity.setGpWtLongMin(String.valueOf(intThe(lzYlGpWtMin)));
		return true;
	}

	/**
	 * 获取模铸锭型
	 * 
	 * @param conn
	 * @param bom
	 * @param gpReqEntity
	 * @param message
	 * @return
	 * @throws SQLException
	 */
	public static boolean getSpindle(Connection conn,
			PlnReqinfGpEntity gpReqEntity, String[] message,
			String zgPlineCode, String desginKey, String mscPline)
			throws SQLException {
		PreparedStatement ps = null;
		ResultSet rs = null;
		String sql = "";
		int cutNum = 0;// 倍尺数
		double ZzSingle = 0;// 管坯长度(mm)
		double wastWt = 0;
		String specCodeZz = "";// 铸造规格代码
		String specNameZz = "";// 铸造规格
		String outMaterialNo = "";// 产出物料
		String outMaterialNm = "";// 产出物料
		double zgGpSingle = Double.parseDouble(gpReqEntity.getLenGpSingle()); // 轧管单倍坯长
		double zgDiameterGp = Double.parseDouble(gpReqEntity.getDiameterGp());// 轧管断面
		double zgwtSingle = CoreOrdBase.GpweightOfmi(zgDiameterGp); // 轧管坯米单重
		double wjJgallow = 20;// 锻坯外径加工余量=20mm
		double cutHeadEnd = 200;// 锻坯头尾切损长=200mm
		double cutLenBurn = 0;// 倍尺坯分切长度损失（mm）
		gpReqEntity.setDzLoseAdd(String.valueOf(wjJgallow));
		gpReqEntity.setDzCutHeadEnd(String.valueOf(cutHeadEnd));

		//  锻造后外径：=轧管截面+锻坯外径加工余量
		double outDiameter = zgDiameterGp + wjJgallow;
		//  锻造后单倍坯长：=单倍坯长+锻坯头尾切损长
		ZzSingle = zgGpSingle + cutHeadEnd;
		//  锻造后单倍坯重：=7.8*3.1415926* (轧管截面+锻坯外径加工余量)* (轧管截面+锻坯外径加工余量)/4 *
		// (单倍坯长+锻坯头尾切损长)/1000/1000/1000
		double dzSWtLong = 7.8 * Pi * outDiameter * (outDiameter / 4)
				* ZzSingle / 1000 / 1000 / 1000;
		double dzSingleN = 0;// 锻造后N倍坯长
		double dzSWtLongN = 0;//  锻造后N倍坯重
		double blankSinGpWt = 0;// 毛坯重量
		double spindleSin = 0;// 锭坯单重
		double blankSinGpWt1 = 0;// 毛坯重量1

		String messg = "";
		// 获取最佳锻造产线
		double burning = 0; // 烧损(%)
		sql = CoreXmlSqlParsersFactory
				.getSql("CorePlnZgMStoGp.selectProcessCPline");
		if (gpReqEntity.getIfbuyplan().equals("1")) {
			sql += " AND B.PLINE_CODE = 'C064'";
			messg = "外购";
		} else {
			sql += " AND B.PLINE_CODE NOT IN ('C064')";
			messg = "自炼";
		}
		sql += " ) ORDER BY T.PLINE_LEVEL ASC, T.PLINE_CODE ASC";
		ps = conn.prepareStatement(sql);
		ps.setObject(1, gpReqEntity.getWlidZz());
		ps.setObject(2, gpReqEntity.getMaterialNo());
		ps.setObject(3, desginKey);
		ps.setObject(4, mscPline);
		rs = ps.executeQuery();
		while (rs.next()) {
			double lenMax = 0;
			double lenMin = 0;
			lenMin = rs.getDouble("LENGTH_MIN") * 1000;
			lenMax = rs.getDouble("LENGTH_MAX") * 1000;

			burning = rs.getDouble("BURNOUT_RATE");
			int n = 1;
			do {

				//  锻造后N倍坯长：=N*单倍坯长+锻坯头尾切损长+（N-1）*10mm
				dzSingleN = n * zgGpSingle + cutHeadEnd + (n - 1) * 10;
				//  锻造后N倍坯重：=7.8*3.1415926* (轧管截面+锻坯外径加工余量)* (轧管截面+锻坯外径加工余量)/4
				// *
				// (N*单倍坯长+(N-1)*10+锻坯头尾切损长)/1000/1000/1000
				dzSWtLongN = 7.8 * Pi * outDiameter * outDiameter / 4
						* dzSingleN / 1000 / 1000 / 1000;

				if (dzSWtLongN <= 10.5) {
					// 获取最佳锭型
					String sqldx = CoreXmlSqlParsersFactory
							.getSql("CorePlnZgMStoGp.getMscCastRForg");
					sqldx += " AND TRIM(T.SPEC_CODE_INGOT) IS NOT NULL"
							+ " AND S2.WEIGHT IS NOT NULL";
					PreparedStatement ps1 = conn.prepareStatement(sqldx);
					ps1.setObject(1, zgDiameterGp);
					ResultSet rs1 = ps1.executeQuery();
					while (rs1.next()) {
						double wastWted = 0;// 余量
						if (rs1.getString("WEIGHT") == null) {
							continue;
						}
						// 倍尺坯长
						double dis = n * zgGpSingle + (n - 1) * 10 + cutHeadEnd;
						if (dis >= lenMin) {// 倍尺坯长要大于等于产线最小
							blankSinGpWt = Double.parseDouble(rs1
									.getString("ACTUAL_WEIGHT"));// 实重
							wastWted = blankSinGpWt * (1 - burning / 100)
									- dzSWtLongN;
							if (wastWt == 0 || wastWted < wastWt
									&& wastWted >= 0) {
								wastWt = wastWted;

								if (dis <= lenMax) {// 倍尺坯长要小于等于产线最小大
									cutNum = n;// 倍尺数
									blankSinGpWt1 = Double.parseDouble(rs1
											.getString("ACTUAL_WEIGHT"));// 实重
									spindleSin = Double.parseDouble(rs1
											.getString("WEIGHT"));// 锭坯单重
									specCodeZz = rs1
											.getString("SPEC_CODE_INGOT");// 锭型
									specNameZz = rs1
											.getString("SPEC_NAME_INGOT");
									gpReqEntity.setPlineCodeDz(rs
											.getString("PLINE_CODE"));
									gpReqEntity.setPlineNameDz(rs
											.getString("PLINE_NAME"));
									gpReqEntity.setDzBurnLose(String
											.valueOf(burning));
								}
							}
						}

					}
					rs1.close();
					ps1.close();
					n++;
				}
			} while (dzSWtLongN <= 10.5);
		}
		rs.close();
		ps.close();

		if (specCodeZz.equals("")) {
			message[0] = "未找到合适锭型。";
			return false;
		}
		// 需锭数量= int (单倍坯支数 / 倍尺数+0.85)
		// int gpNumLong = (int) (Double.parseDouble(gpReqEntity.getGpNum())
		// / cutNum + 0.85);
		int gpNumLong = (int) Math.ceil(Double.parseDouble(gpReqEntity
				.getGpNum())
				/ cutNum);
		int gpNumMin = (int) Math.floor((Double.parseDouble(gpReqEntity
				.getGpNum())
				/ Double.parseDouble(gpReqEntity.getGpWeight()) * Double
				.parseDouble(gpReqEntity.getGpWeightMin()))
				/ cutNum);
		// 需锭吨=需锭数量*毛坯重t
		double gpWtLong = gpNumLong * blankSinGpWt1;
		// int gpNumMin = (int)
		// ((Double.parseDouble(gpReqEntity.getGpWeightMin()) / Double
		// .parseDouble(gpReqEntity.getWeightGpOne()))
		// / cutNum + 0.85);
		double gpWtLongMin = gpNumMin * blankSinGpWt1;
		// 倍尺坯分切长度损失（mm） =（倍尺数-1）*10mm
		cutLenBurn = (cutNum - 1) * 10;
		dzSingleN = cutNum * zgGpSingle + cutLenBurn + cutHeadEnd;
		gpReqEntity.setCutNumGp(String.valueOf(cutNum));
		gpReqEntity.setWtOneZz(String.valueOf(intThe(blankSinGpWt1)));
		gpReqEntity.setOutNumZz(String.valueOf(gpNumLong));
		gpReqEntity.setOutWtZz(String.valueOf(intThe(gpWtLong)));
		gpReqEntity.setCutLoseLen(String.valueOf(cutLenBurn));
		gpReqEntity.setLengthGp(String.valueOf(dzSingleN));
		gpReqEntity.setGpNumLong(String.valueOf(gpNumLong));
		gpReqEntity.setGpWtLong(String.valueOf(intThe(gpWtLong)));
		gpReqEntity.setDiameterZz(String.valueOf(spindleSin));
		gpReqEntity.setLengthZz("");
		gpReqEntity.setGpWeightMin(gpReqEntity.getGpWeightMin());
		gpReqEntity.setGpWtLongMin(String.valueOf(intThe(gpWtLongMin)));
		double lengthmaxZg = 0; // 轧管最大长度
		double lengthminZg = 0; // 轧管最小长度

		// 轧管产线长度范围
		sql = CoreXmlSqlParsersFactory
				.getSql("CorePlnZgMStoGp.selectBasePlineCode");
		PreparedStatement pst = conn.prepareStatement(sql);
		pst.setObject(1, zgPlineCode);
		ResultSet rst = pst.executeQuery();
		if (rst.next()) {
			lengthmaxZg = rst.getDouble("IN_MATERIAL_LEN_MAX");
			lengthminZg = rst.getDouble("IN_MATERIAL_LEN_MIN");
		}
		rst.close();
		pst.close();
		int numberRuler = 0;
		// 获取最佳铸造产线
		outMaterialNo = "PD" + specCodeZz + gpReqEntity.getGradecode();
		outMaterialNm = "PD" + specNameZz + "," + gpReqEntity.getGradename();
		sql = CoreXmlSqlParsersFactory
				.getSql("CorePlnZgMStoGp.selectProcessBPline");
		if (gpReqEntity.getIfbuyplan().equals("1")) {
			sql += " AND B.PLINE_CODE = 'C063'";
		} else {
			sql += " AND B.PLINE_CODE NOT IN ('C063')";
		}
		sql += " ) ORDER BY T.PLINE_LEVEL ASC, T.PLINE_CODE ASC";
		pst = conn.prepareStatement(sql);
		pst.setObject(1, gpReqEntity.getGradecode());
		pst.setObject(2, outMaterialNo);
		pst.setObject(3, String.format("%.2f", zgDiameterGp));
		pst.setObject(4, desginKey);
		pst.setObject(5, mscPline);
		rst = pst.executeQuery();
		while (rst.next()) {
			double lengthmax = 0; // 前工序最大长度
			double lengthmin = 0; // 前工序最小长度
			double casLengMax = 0;// 坯子长度上限
			double casLengMin = 0;// 坯子长度下限
			lengthmax = rst.getDouble("LENGTH_MAX");
			lengthmin = rst.getDouble("LENGTH_MIN");

			// 前工序成品转移最长or轧管原料进厂最长，取二者最小
			if (lengthmax > lengthmaxZg) {
				casLengMax = lengthmaxZg;
			} else {
				casLengMax = lengthmax;
			}
			// 坯子长度下限：前工序成品转移最短or轧管原料进厂最短，取二者最大
			if (lengthmin > lengthminZg) {
				casLengMin = lengthmin;
			} else {
				casLengMin = lengthminZg;
			}
			// 最大长度必须大于零
			if (casLengMax <= 0) {
				message[0] = "坯子长度上限必须大于零。";
				return false;
			}

			// 最小长度必须大于等于零
			if (casLengMin < 0) {
				message[0] = "坯子长度下限必须大于等于零。";
				return false;
			}
			// x=int (坯子长度下限 / 单倍坯长)
			int x = (int) (casLengMin / (zgGpSingle / 1000));
			if (x * (zgGpSingle / 1000) < casLengMin) {
				x = x + 1;
			}
			int y = (int) (casLengMax / (zgGpSingle / 1000));
			int waseTim = 0;
			if (x > y) {
				waseTim = y;
			} else {
				// 获取最小整数
				int min = CoreIsRounded.isRounded(x, y);
				if (min != 0) {
					waseTim = min;
				}
			}
			if (gpReqEntity.getIfbuyplan().equals("0")) {
				if (zgPlineCode.equals("C008")) {// 轧管250
					if (rst.getString("PLINE_CODE") != null
							&& rst.getString("PLINE_CODE").equals("C002")) {// 一炼铸机
						numberRuler = waseTim;
						gpReqEntity.setPlineCodeZz(rst.getString("PLINE_CODE"));
						gpReqEntity.setPlineNameZz(rst.getString("PLINE_NAME"));
					}
					break;
				}
			}
			// 取最小倍尺数
			if (waseTim < numberRuler || numberRuler == 0) {
				numberRuler = waseTim;
				gpReqEntity.setPlineCodeZz(rst.getString("PLINE_CODE"));
				gpReqEntity.setPlineNameZz(rst.getString("PLINE_NAME"));
			}
			// 倍尺数为1 时调出循环
			if (numberRuler == 1) {
				break;
			}
		}
		rst.close();
		pst.close();
		gpReqEntity.setWlidZz(outMaterialNo);
		gpReqEntity.setWldescZz(outMaterialNm);

		return true;
	}

	/**
	 * 获取单倍尺毛坯重量
	 * 
	 * @param diameterDz
	 *            管坯断面（mm）
	 * @param sinGplen
	 *            单倍坯长度（mm）
	 * @param dzLoseAdd
	 *            加工余量（mm）
	 * @param dzCutHeadEnd
	 *            切头尾量（mm）
	 * @return
	 */
	public static double getBlankSinGpWt(double diameterDz, double sinGplen,
			double dzLoseAdd, double dzCutHeadEnd) {
		double blankSinGpWt = 0;
		blankSinGpWt = Pi
				* ((diameterDz + dzLoseAdd) * 0.001 * (diameterDz + dzLoseAdd)
						* 0.001 / 2) * (sinGplen + dzCutHeadEnd) * 0.001 * P;
		return blankSinGpWt;
	}

	/**
	 * 实现4舍5进
	 * 
	 * @param d
	 * @return
	 */
	public static double intThe(double d) {
		BigDecimal bg = new BigDecimal(d).setScale(3, RoundingMode.HALF_UP);
		return bg.doubleValue();
	}

}