package com.steering.pss.plnsaleord.ordAmCal;

import CoreFS.SA08.CoreXmlSqlParsersFactory;
import com.steering.pss.plnsaleord.base.CoreUnitConvert;
import com.steering.pss.plnsaleord.lenthCal.CoreLenCalculate;
import com.steering.pss.plnsaleord.lenthCal.LenCalculateInObject;
import com.steering.pss.plnsaleord.lenthCal.LenCalculateOutObject;
import com.steering.pss.plnsaleord.lenthCal.PlnZglenthCal;
import com.steering.pss.plnsaleord.ordAmCal.model.InOrdParamEntity;
import com.steering.pss.plnsaleord.ordAmCal.model.OutOrdParamEntity;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 合同量转换原则
 * @author tjg 2017-04-19
 */
public class PlnProducCal {

    /**
     * 合同量转换
     * @param InOrdParamEntity
     * @return
     */
    public static OutOrdParamEntity calculate(Connection conn,
            InOrdParamEntity inEntity) {
        OutOrdParamEntity outEntity = new OutOrdParamEntity();
        PreparedStatement ps = null;
        ResultSet rs = null;
        // Connection conn = null;
        String[] errMessage = new String[1];
        if (!isAvailable(inEntity, errMessage)) {
            outEntity.setErrCode(-1);
            outEntity.setErrMessage(errMessage[0]);
            return outEntity;
        }

        try {
            // conn = this.getDao(CoreConstantData.sysbeanstr).getConnection();
            // conn.setAutoCommit(false);
            double orderQtyS = 0; // 订货量S
            String orderUnitS = ""; // 订货量S单位
            double cutHeadEnd = inEntity.getCutHeadEnd() / 1000;// 切头尾(m)

            double weightMik = 0;// 控制壁厚米单重
            double lenOneGp = 0;// 单支产出成品长度(m)
            double lenthRoll = 0;// 轧制长度（m）
            int cutNum = 0;// 分切数
            double lengthZg = 0;// 目标轧管转移长度(m)
            double lengthMaxZg = 0;// 目标轧管转移长度上限(m)
            double lengthMinZg = 0;// 目标轧管转移长度下限(m)
            double totlengthM = 0;// 保总长（m）
            int orderNum = 0;// 排产支数
            double estWeight = 0;// 估算量
            double inAweight = 0;// 缴库量
            double tuboWeight = 0;// 管体重量(t)
            double weightPc = 0;// 排产量
            double weightPcMin = 0;// 排产量min
            double delvryRangeMax = 0;// 交货量差上限
            double delvryRangeMin = 0;// 交货量差下限
            double wJ = 0;// 选用米单重
            double aimHeight = 0;// 选用壁厚
            double aimOutDiam = 0;// 目标外径
            double weightMiw = 0;// 名义米单重W
            double weightMiw1 = 0;// 交货米单重W1
            double weightMiw2 = 0;// 内控米单重W2
            double weightMiw3 = 0;// 负公差米单重W3
            double heightJ = 0;// 壁厚J
            double heightN = 0;// 壁厚N
            double heightF = 0;// 壁厚F
            double outDiamJ = 0;// 外径J
            double outDiamN = 0;// 外径N
            double outDiamF = 0;// 外径F
            double addlenZg = 0;// 轧制加长(m)
            double addWeightZg = 0;// 轧制加长重(t)
            double addWeightDc = 0;// 钝粗加长重(t)
            double addWeightDbk = 0;// 镦拔扩加长重(t)
            double addWeightInspect = 0;// 盲区切长重(t)
            double weightJgAll = 0;// 接箍重(t)

            int numOutMultD = 0; // 轧管产出倍尺数
            double plineLenMin = 0; // 轧管产线长度下限
            double plineLenMax = 0; // 轧管产线长度上限


            // 查询制程
            String sql = CoreXmlSqlParsersFactory
                    .getSql("CorePlnProcessOrd.queryDesginMscpl");
            ps = conn.prepareStatement(sql);
            ps.setString(1, inEntity.getDesginKey());
            ps.setString(2, inEntity.getIndexSeq());
            rs = ps.executeQuery();
            if (rs.next()) {
                if (rs.getString("WHOLE_BACKLOG") == null) {
                    outEntity.setErrCode(-1);
                    return outEntity;
                }
                inEntity.setWholeBacklog(rs.getString("WHOLE_BACKLOG"));
                inEntity.setWholeBacklogDesc(rs.getString("WHOLE_BACKLOG_DESC"));
            } else {
                outEntity.setErrCode(-1);
                return outEntity;
            }
            rs.close();
            ps.close();

            // 拔扩变径比
            double rateEtoD = PlnZglenthCal.getDhChangeRate(inEntity
                    .getOutdiameter(), inEntity.getWallthick(), inEntity
                    .getDiameterZg(), inEntity.getHeightZg(), inEntity
                    .getBurnoutDbk());
            if (rateEtoD > 1) {
                rateEtoD = 1;
            }
            // 轧管产线长度上限、下限
            plineLenMin = inEntity.getPlineLenMin();
            plineLenMax = inEntity.getPlineLenMax();
            // 交货量差统一转换为百分比
            if (inEntity.getDelvryRangeTpe() == 2) {
                delvryRangeMax = (inEntity.getDelvryRangeMax() / inEntity
                        .getOrderQty()) * 100;
                delvryRangeMin = (inEntity.getDelvryRangeMin() / inEntity
                        .getOrderQty()) * 100;
            }
            else {
                delvryRangeMax = inEntity.getDelvryRangeMax();
                delvryRangeMin = inEntity.getDelvryRangeMin();
            }
            // 上限>=15% and“上限-下限”>15%
            if (delvryRangeMax >= 15 && delvryRangeMax - delvryRangeMin > 15) {
                delvryRangeMax = 15;
            }
            // 排产系数
            double rate = 1 + ((delvryRangeMax - delvryRangeMin)
                    * inEntity.getPutRate() + delvryRangeMin) / 100;
            // 最小排产系数
            double rateMin = 1 - (delvryRangeMin / 100);
            // 保米长排产系数=（交货量差上限+下限）*投料率/100
            double rateTot = (delvryRangeMax + delvryRangeMin)
                    * inEntity.getPutRate() / 100;
            // 如果保总长单位是英尺，计算保米长量，如果保总长单位是米，保米长等于保总长，否则保米长为0
            if (inEntity.getTotlengthUnit().trim().equals("英尺")) {
                totlengthM = CoreUnitConvert.FootoMi(inEntity.getTotlength());
            }
            else if (inEntity.getTotlengthUnit().trim().equals("米")) {
                totlengthM = inEntity.getTotlength();
            }
            else {
                totlengthM = 0;
            }

            // 计算订货量S，如果订货量单位为支，订货量不变，如果订货量单位为个，订货量不变，单位改为支；
            if (inEntity.getOrderUnit().trim().equals("支")) {
                orderQtyS = inEntity.getOrderQty();
                orderUnitS = "支";
            }
            else if (inEntity.getOrderUnit().trim().equals("个")) {
                orderQtyS = inEntity.getOrderQty();
                orderUnitS = "支";
            }
            // 如果订货量单位为吨，并且保米长大于0，则订货量为保米长，订货单位改为米，如果无保米长，订货单位为吨，订货量为合同量；
            else if (inEntity.getOrderUnit().trim().equals("吨")) {
                if (totlengthM > 0) {
                    orderQtyS = totlengthM;
                    orderUnitS = "米";
                }
                else {
                    orderQtyS = inEntity.getOrderQty();
                    orderUnitS = "吨";
                }
            }
            // 如果订货量单位为英镑，并且保米长大于0，则订货量为保米长，订货单位改为米，如果无保米长，订货单位为吨，订货量为合同量从英镑转换为吨；
            else if (inEntity.getOrderUnit().trim().equals("英磅")) {
                if (totlengthM > 0) {
                    orderQtyS = totlengthM;
                    orderUnitS = "米";
                }
                else {
                    orderQtyS = CoreUnitConvert.PoundtoTon(inEntity
                            .getOrderQty());
                    orderUnitS = "吨";
                }
            }
            else if (inEntity.getOrderUnit().trim().equals("米")) {
                orderQtyS = inEntity.getOrderQty();
                orderUnitS = "米";
            }
            else if (inEntity.getOrderUnit().trim().equals("英尺")) {
                orderQtyS = CoreUnitConvert.FootoMi(inEntity.getOrderQty());
                orderUnitS = "米";
            }

            if (orderUnitS.trim().equals("支")) {
                // 附件按支交货
                orderNum = (int) orderQtyS;
                estWeight = orderQtyS;
                inAweight = orderQtyS;
                weightPc = orderQtyS;
                weightJgAll = orderNum * inEntity.getWeightJg() / 1000;

                outEntity.setWeightInA(inAweight);
                outEntity.setWeightInAMax(inAweight
                        * (1 + delvryRangeMax / 100));
                outEntity.setWeightInAMin(inAweight
                        * (1 - delvryRangeMin / 100));
                outEntity.setWeightPc(weightPc);
                outEntity.setEstWeight(estWeight);
                outEntity.setWeightUnit("支");
                outEntity.setPlanNum(orderNum);
                return outEntity;
            }

            double addlenZgRuleMax = PlnZglenthCal.addLenZgRuleMaxS(inEntity
                    .getLengthMax(), inEntity.getLengthMin(), inEntity
                    .getModelDesc());// 轧管加长原则上限(mm)
            double addlenZgRuleMin = PlnZglenthCal.addLenZgRuleMinS(inEntity
                    .getLengthMax(), inEntity.getLengthMin(), inEntity
                    .getModelDesc());// 轧管加长原则下限(mm)

            // 机组公差能力带默认壁厚的20%
            if (inEntity.getPlineWallthick() == 0) {
                inEntity.setPlineWallthick(0.2 * inEntity.getHeightZg());
            }
            heightJ = inEntity.getWallthick()
                    + (inEntity.getStdWallthickMax() -Math.abs(inEntity
                            .getStdWallthickMin())) / 2;

            heightN = inEntity.getHeightZg()
                    + (inEntity.getNkWallthickMax() - Math.abs(inEntity
                            .getNkWallthickMin())) / 2;

            // 壁厚内控的范围与公差带比较
            if (inEntity.getNkWallthickMax()
                    - Math.abs(inEntity.getNkWallthickMin()) >= inEntity
                    .getPlineWallthick()) {
                heightF = inEntity.getHeightZg() + inEntity.getNkWallthickMin()
                        + (inEntity.getPlineWallthick() / 2);
            }
            else {
                heightF = heightN;
            }

            // double numPlineOutDiam = 0.2 * inEntity.getOutdiameter();
            outDiamJ = inEntity.getOutdiameter()
                    + (inEntity.getOutdOrdMax() - Math.abs(inEntity.getOutdOrdMin())) / 2;

            outDiamN = inEntity.getDiameterZg()
                    + (inEntity.getNkAimthickMax() - Math.abs(inEntity.getNkAimthickMin())) / 2;
            // 外径内控的范围与公差带比较
            /*
             * if (inEntity.getOutdOrdMax() - inEntity.getOutdOrdMin() >=
             * numPlineOutDiam) { outDiamF = inEntity.getOutdiameter() +
             * inEntity.getOutdOrdMin() + (numPlineOutDiam / 2); } else {
             * outDiamF = outDiamN; }
             */
            outDiamF = outDiamN;
            // 名义米单重w计算
            weightMiw = tubeWeightMi(inEntity.getOutdiameter(), inEntity
                    .getWallthick());
            // 交货米单重w1计算
            weightMiw1 = tubeWeightMi(outDiamJ, heightJ);
            if (weightMiw1 == 0) {
                weightMiw1 = weightMiw;
            }
            // 内控米单重w2计算
            weightMiw2 = tubeWeightMi(outDiamN, heightN);
            if (weightMiw2 == 0) {
                weightMiw2 = weightMiw1;
            }
            // 负公差米单重w3计算
            weightMiw3 = tubeWeightMi(outDiamF, heightF);
            if (weightMiw3 == 0) {
                weightMiw3 = weightMiw1;
            }
            if (inEntity.getOrderUnit().trim().equals("英磅")
                    || inEntity.getOrderUnit().trim().equals("吨")) {
                if (inEntity.getWeightType() == 1) {
                    aimHeight = heightN;
                    aimOutDiam = outDiamN;
                    wJ = weightMiw2;
                }
                else {
                    aimHeight = heightF;
                    aimOutDiam = outDiamF;
                    wJ = weightMiw3;
                }
            }
            else {
                aimHeight = heightF;
                aimOutDiam = outDiamF;
                wJ = weightMiw3;
            }

            if (wJ == weightMiw1) {
                aimHeight = heightJ;
                aimOutDiam = outDiamJ;
            }
            int cutJg = 1;
            // 如果订货单位不为支，推算轧管转移长度上限、下限，
            // 评审环节
            if (!orderUnitS.trim().equals("支")) {
                numOutMultD = 0;
                // 循环验证轧管转移长度上下限和产线长度范围，不满足时考虑轧管产出为多倍尺情况，得到轧管产出倍尺数
                // do {
                // numOutMultD = numOutMultD + 1;
                //
                // lengthMaxZg = PlnZglenthCal.lenthZgCal(inEntity
                // .getLengthMax(), rateEtoD, inEntity
                // .getAddLengthDc(), inEntity.getAddLengthDbk(),
                // inEntity.getInspectLen(), inEntity.getCheckJVal(),
                // addlenZgRuleMax, numOutMultD);
                // lengthMinZg = PlnZglenthCal.lenthZgCal(inEntity
                // .getLengthMin(), rateEtoD, inEntity
                // .getAddLengthDc(), inEntity.getAddLengthDbk(),
                // inEntity.getInspectLen(), inEntity.getCheckJVal(),
                // addlenZgRuleMin, numOutMultD);
                // }
                // while (lengthMaxZg < plineLenMin);
                double lengMax = PlnZglenthCal.lenthZgCal(inEntity
                                .getLengthMax(), rateEtoD, inEntity.getAddLengthDc(),
                        inEntity.getAddLengthDbk(), inEntity.getInspectLen(),
                        inEntity.getCheckJVal(), addlenZgRuleMax);
                double lengMin = PlnZglenthCal.lenthZgCal(inEntity
                                .getLengthMin(), rateEtoD, inEntity.getAddLengthDc(),
                        inEntity.getAddLengthDbk(), inEntity.getInspectLen(),
                        inEntity.getCheckJVal(), addlenZgRuleMin);

                if (plineLenMax > totlengthM && totlengthM != 0) {
                    cutJg = (int) ( totlengthM / lengMax );
                } else {
                    cutJg = (int) ( plineLenMax / lengMax );
                }
                // cutJg = (int) (plineLenMax / lengMax);
                if (cutJg == 0) {
                    cutJg = 1;
                }
                double lengMax1 = PlnZglenthCal.lenthZgCal(inEntity
                                .getLengthMax(), rateEtoD, inEntity.getAddLengthDc(),
                        inEntity.getAddLengthDbk(), inEntity.getInspectLen(),
                        inEntity.getCheckJVal(), 0);
                double lengMin1 = PlnZglenthCal.lenthZgCal(inEntity
                                .getLengthMin(), rateEtoD, inEntity.getAddLengthDc(),
                        inEntity.getAddLengthDbk(), inEntity.getInspectLen(),
                        inEntity.getCheckJVal(), 0);
                lengthMaxZg = new BigDecimal(lengMax1 * cutJg + ( cutJg - 1 )
                        * 0.02 + addlenZgRuleMax / 1000).setScale(2,
                        RoundingMode.HALF_UP).doubleValue();
                // 循环验证轧管转移长度上下限和产线长度范围
                do {
                    if (lengthMaxZg > plineLenMax) {
                        cutJg = cutJg - 1;
                        if (cutJg <= 0) {
                            cutJg = 1;
                            lengthMaxZg = new BigDecimal(lengMax1 * cutJg
                                    - ( cutJg - 1 ) * 0.02 + addlenZgRuleMax
                                    / 1000).setScale(2, RoundingMode.HALF_UP)
                                    .doubleValue();
                            break;
                        }
                        lengthMaxZg = new BigDecimal(lengMax1 * cutJg
                                - ( cutJg - 1 ) * 0.02 + addlenZgRuleMax / 1000)
                                .setScale(2, RoundingMode.HALF_UP)
                                .doubleValue();
                    }
                }
                while (lengthMaxZg > plineLenMax);

                lengthMinZg = new BigDecimal(lengMin1 * cutJg + ( cutJg - 1 )
                        * 0.02 + addlenZgRuleMin / 1000).setScale(2,
                        RoundingMode.HALF_UP).doubleValue();
                // 如果轧管转移长度下限小于产线长度下限，则取产线长度下限为轧管转移长度下限
                if (lengthMinZg < plineLenMin) {
                    lengthMinZg = plineLenMin;
                }
                // 如果轧管转移长度上限大于产线长度上限，则取产线长度上限为轧管转移长度上限
                if (lengthMaxZg > plineLenMax) {
                    lengthMaxZg = plineLenMax;
                }
               //2020.3.6新增判断  如果最终转移上限<转移下限 则 转移上限 = 转移下限
                if (lengthMaxZg < lengthMinZg)
                {
                    lengthMaxZg = lengthMinZg;
                }

                // 如果轧管转移长度下限大于产线长度上限，则轧管转移长度上下限超出产线范围，无法生产
                if (lengthMinZg > plineLenMax) {
                    outEntity.setErrCode(-1);
                    outEntity.setErrMessage("轧管转移长度上下限超出产线范围,转移长度范围:"
                            + lengthMinZg + "~" + lengthMaxZg + ",产线范围:"
                            + plineLenMin + "~" + plineLenMax + "");
                    return outEntity;
                }

                LenCalculateInObject lenCalIn = new LenCalculateInObject();
                LenCalculateOutObject lenCalOut = new LenCalculateOutObject();

                // 查询测量J值和平均长度大于
                sql = CoreXmlSqlParsersFactory
                        .getSql("CoreGetOrdAmount.getChekJAve");
                ps = conn.prepareStatement(sql);
                ps.setObject(1, inEntity.getOrdLnDlyPk());
                rs = ps.executeQuery();
                if (rs.next()) {
                    lenCalIn.setAvgLenMin(rs.getDouble("AVG_LEN_MIN"));
                    lenCalIn.setCheckJVal(rs.getDouble("CHECK_J_VAL"));
                }
                else {
                    lenCalIn.setAvgLenMin(0.0);
                    lenCalIn.setCheckJVal(0.0);
                }
                rs.close();
                ps.close();
                lenCalIn.setCutMax(inEntity.getCutMax());
                lenCalIn.setEndlenSpecstd(inEntity.getEndlenSpecstd());
                lenCalIn.setTubeEndRatio(inEntity.getTubeEndRatio());
                lenCalIn.setToleranceZone(inEntity.getToleranceZone());
                lenCalIn.setOutdiameter(inEntity.getDiameterZg());
                lenCalIn.setWallthick(inEntity.getHeightZg());
                lenCalIn.setWallUpper(inEntity.getNkWallthickMax());
                lenCalIn.setWallLower(inEntity.getNkWallthickMin());
                lenCalIn.setAimUpper(inEntity.getNkAimthickMax());
                lenCalIn.setAimLower(inEntity.getNkAimthickMin());
                lenCalIn.setShrtstove(inEntity.isShrtStove());
                // if (addlenZgRuleMax == 0) {
                lenCalIn.setSigllen(inEntity.getSigllen());
                // }
                // else {
                // lenCalIn.setSigllen(0);
                // }
                lenCalIn.setBurning(inEntity.getBurnoutRate());
                lenCalIn.setDiameter(inEntity.getDiameterPl());
                lenCalIn.setLengthmax(inEntity.getLengthMax());
                lenCalIn.setLengthmin(inEntity.getLengthMin());
                lenCalIn.setLengthmaxZg(lengthMaxZg);
                lenCalIn.setLengthminZg(lengthMinZg);
                lenCalIn.setCutheadtail(cutHeadEnd);
                lenCalIn.setBilletmax(inEntity.getLengthMaxRing());
                lenCalIn.setSizing(inEntity.getLengthColdbed());
                lenCalIn.setFootmin(inEntity.getFootmin());
                lenCalIn.setOutdiamMax(inEntity.getOutdOrdMax());
                lenCalIn.setOutdiamMin(inEntity.getOutdOrdMin());
                // lenCalIn.setAvgLenMin(inEntity.getAvgLenMin());
                // lenCalIn.setCheckJVal(inEntity.getCheckJVal());
                lenCalIn.setOrderUnit(inEntity.getOrderUnit());
                lenCalIn.setWeighType(String.valueOf(inEntity.getWeightType()));
                // 粗算
                // LenCalculateOutObject outParams1
                lenCalOut = CoreLenCalculate.comput(lenCalIn, false);
                // 圆整最佳单倍坯长并代入重算
                // double floorBilletLen = 10 * Math.floor((Double
                // .parseDouble(outParams1.getBillet())) / 10);
                // lenCalIn.setBilletmax(floorBilletLen);
                //
                // lenCalOut = CoreLenRecalCulation.recaComput(lenCalIn, false);
                if (!lenCalOut.getisOutput()) {
                    outEntity.setErrCode(-1);
                    outEntity.setErrMessage(lenCalOut.getReason());
                    return outEntity;
                }
                weightMik = lenCalOut.getMiGtWt();// 控制壁厚米单重
                aimHeight = Double.parseDouble(lenCalOut.getAimwallthick());
                aimOutDiam = lenCalOut.getAimoutdiameter();
                lenthRoll = Double.parseDouble(lenCalOut.getLengthZz());// 轧制长度
                cutNum = Integer.parseInt(lenCalOut.getCutnum());// 分切数
                lengthZg = Double.parseDouble(lenCalOut.getAimlength());// 目标轧管转移长度
                addlenZg = addlenZgRuleMax / 1000;// 轧管加长
                // 单倍坯产出目标长度=（轧制长度-轧管切头尾）/变径比
                // -分切数*（镦拔扩切头尾+镦粗加长*轧管产出倍尺数+探伤盲区切长+轧管加长原则上限
                // -接箍J值*轧管产出倍尺数）/1000
                lenOneGp = (lenthRoll - cutHeadEnd)
                        / rateEtoD
                        - cutNum
                        * (inEntity.getAddLengthDbk()
                                + inEntity.getAddLengthDc() * numOutMultD
                                + inEntity.getInspectLen() + addlenZgRuleMax - inEntity
                                .getCheckJVal()
                                * numOutMultD) / 1000;
            }

            // 成品单支长
            double aimlength = inEntity.getLengthMin()
                    + (inEntity.getLengthMax() - inEntity.getLengthMin()) * 0.9;
            // 成品单支重量
            double tuboWeightOne = inEntity.getWeightJg() / 1000 + weightMiw
                    * (aimlength - inEntity.getCheckJVal() / 1000);
            // _start 排产
            if (orderUnitS.trim().equals("吨")) {
                if (totlengthM > 0) {
                    // 排产系数*（订货量*（1-订货量差下限））/排产成品单支长
                    orderNum = (int) Math
                            .ceil(((orderQtyS * (1 + delvryRangeMin / 100)) / aimlength));
                    // 排产系数*（订货量*（1-订货量差下限））-管体排产支*接箍J值）*成品米单重
                    weightPc = (rate * (orderQtyS * (1 + delvryRangeMin / 100)) - orderNum
                            * inEntity.getCheckJVal() / 1000)
                            * weightMiw;
                    // 排产系数min*（订货量*（1-订货量差下限））-管体排产支*接箍J值）*成品米单重
                    weightPcMin = (rateMin
                            * (orderQtyS * (1 + delvryRangeMin / 100)) - orderNum
                            * inEntity.getCheckJVal() / 1000)
                            * weightMiw;
                }
                else {
                    // 排产系数*订货量/排产成品单支重
                    orderNum = (int) Math
                            .ceil((rate * orderQtyS / tuboWeightOne));
                    // 排产系数*（订货量-管体排产支*接箍单支重）
                    weightPc = rate
                            * (orderQtyS - orderNum * inEntity.getWeightJg()
                                    / 1000);
                    // 排产系数min*（订货量-管体排产支*接箍单支重）
                    weightPcMin = rateMin
                            * (orderQtyS - orderNum * inEntity.getWeightJg()
                                    / 1000);
                }
                estWeight = orderQtyS;
                inAweight = orderQtyS;
                tuboWeight = orderQtyS
                        - (orderNum * inEntity.getWeightJg() / 1000);
            }
            else if (orderUnitS.trim().equals("米")) {
                // 排产系数*订货量/排产成品单支长
                orderNum = (int) Math.ceil((rate * orderQtyS / aimlength));

                if (inEntity.getWholeBacklog().contains("E")) {
                    // 排产系数*（订货量-管体排产支*接箍J值）*成品米单重
                    weightPc = rate
                            * (orderQtyS - orderNum * inEntity.getWeightJg() / 1000)
                            * weightMiw1;
                }else {
                    // 排产系数*（订货量-管体排产支*接箍J值）*控制米单重
                    weightPc = rate
                            * (orderQtyS - orderNum * inEntity.getWeightJg() / 1000)
                            * weightMik;
                }

                // 排产系数min*（订货量-管体排产支*接箍J值）*成品米单重
                weightPcMin = rateMin
                        * (orderQtyS - orderNum * inEntity.getWeightJg() / 1000)
                        * weightMiw1;

                estWeight = orderQtyS
                        * weightMiw1
                        + orderNum
                        * (inEntity.getWeightJg()/1000 + weightMiw1
                                * (inEntity.getAddLengthDc() - inEntity
                                        .getCheckJVal())/1000);
                inAweight = orderQtyS
                        * weightMiw1
                        + orderNum
                        * (inEntity.getWeightJg()/1000 + weightMiw1
                                * (inEntity.getAddLengthDc() - inEntity
                                        .getCheckJVal())/ 1000) ;
                tuboWeight = weightMiw1
                        * (orderQtyS - orderNum
                                * (inEntity.getCheckJVal() - inEntity
                                        .getAddLengthDc()) / 1000);
            }
            else {
                outEntity.setErrCode(-1);
                return outEntity;
            }
            // 有保米长 控制米单重 * 保米长
            if(inEntity.getTotlengthM() > 0 && !inEntity.getWholeBacklog().contains("E")){
                weightPc = weightMik * inEntity.getTotlengthM();
            }
            // _end
            // 接箍总重量（吨）（拿排产支形成接箍个数）
            weightJgAll = orderNum * inEntity.getWeightJg() / 1000;
            if (orderUnitS.trim().equals("吨")) {
                outEntity.setWeightMi(weightMiw);
                // 轧制加长重量
                addWeightZg = orderNum * weightMiw * addlenZg;
                // 镦粗加长影响重量
                addWeightDc = orderNum * weightMiw * inEntity.getAddLengthDc() / 1000;
                // 镦粗加长影响重量
                addWeightDbk = orderNum * weightMiw * inEntity.getAddLengthDbk()
                        / 1000;
                // 探伤盲区切长影响重量
                addWeightInspect = orderNum * weightMiw * inEntity.getInspectLen()
                        / 1000;
            }
            else if (orderUnitS.trim().equals("米")) {
                outEntity.setWeightMi(weightMiw1);
                addWeightZg = orderNum * weightMiw1 * addlenZg;
                addWeightDc = orderNum * weightMiw1 * inEntity.getAddLengthDc() / 1000;
                addWeightDbk = orderNum * weightMiw1 * inEntity.getAddLengthDbk()
                        / 1000;
                addWeightInspect = orderNum * weightMiw1 * inEntity.getInspectLen()
                        / 1000;
            }

            outEntity.setRollLength(lenthRoll);
            outEntity.setAimWallthick(aimHeight);
            outEntity.setTotLenOneP(lenOneGp);
            outEntity.setCutNumP(cutNum);
            outEntity.setPlanNum(orderNum);
            outEntity.setAimLength(aimlength);
            outEntity.setAimlengthZg(lengthZg);
            outEntity.setAddLenZg(addlenZg);
            outEntity.setLenToendMax(addlenZgRuleMax);
            outEntity.setLenToendMin(addlenZgRuleMin);
            outEntity.setWeightInA(inAweight);
            outEntity.setWeightInAMax(intThe(inAweight
                    * (1 + delvryRangeMax / 100)));
            outEntity.setWeightInAMin(intThe(inAweight
                    * (1 - delvryRangeMin / 100)));
            outEntity.setWeightPc(intThe(weightPc));
            outEntity.setEstWeight(intThe(estWeight));
            if (orderUnitS.trim().equals("支")) {
                outEntity.setWeightUnit("支");
            }
            else {
                outEntity.setWeightUnit("吨");
            }
            outEntity.setTubebodyWeight(intThe(tuboWeight));
            outEntity.setWeightJgAll(weightJgAll);
            outEntity.setWeightDc(addWeightDc);
            outEntity.setWeightDbk(addWeightDbk);
            outEntity.setWeightZg(addWeightZg);
            outEntity.setWeightInspect(addWeightInspect);
            outEntity.setTotlengthM(totlengthM);
            outEntity.setLenRollMin(lengthMinZg);
            outEntity.setLenRollMax(lengthMaxZg);
            outEntity.setOutMultD(String.valueOf(numOutMultD));
            outEntity.setAimOutdiameter(aimOutDiam);
            outEntity.setFeedRate(inEntity.getPutRate());
            outEntity.setCoefficient(rate);
            outEntity.setCoefficientMin(rateMin);
            outEntity.setPlanPMainMin(intThe(weightPcMin));
            outEntity.setWeightKzM(weightMik);
            outEntity.setAimWtEnd(intThe(tuboWeightOne));
        }
        catch (Exception ex) {
            outEntity.setErrCode(-1);
            outEntity.setErrMessage(ex.getMessage());
        }
        return outEntity;
    }

    /**
     * 直接进位，不四舍五入
     * @param d
     * @return
     */
    public static double intThe(double d) {
        double i = 0;
        i = d + 0.001;
        BigDecimal bg = new BigDecimal(i).setScale(3, RoundingMode.DOWN);
        return bg.doubleValue();
    }

    /**
     * 验证数据是否正常
     * @param inEntity
     * @param errMessage
     * @return
     */
    public static boolean isAvailable(InOrdParamEntity inEntity,
            String[] errMessage) {
        if (!inEntity.getOrderUnit().equals("支")
                && !inEntity.getOrderUnit().equals("英磅")
                && !inEntity.getOrderUnit().equals("吨")
                && !inEntity.getOrderUnit().equals("米")
                && !inEntity.getOrderUnit().equals("英尺")) {
            errMessage[0] = "合同订货单位未知！";
            return false;
        }
        if (inEntity.getOrderQty() <= 0) {
            errMessage[0] = "合同订货量必须大于零！";
            return false;
        }
        if (inEntity.getTotlength() > 0) {
            if (!inEntity.getTotlengthUnit().equals("米")
                    && !inEntity.getTotlengthUnit().equals("英尺")) {
                errMessage[0] = "有保总长，但保总长单位未知！";
                return false;
            }
        }
        if (inEntity.getTotlength() < 0) {
            errMessage[0] = "保总长不能为负数！";
            return false;
        }
        if (!inEntity.getOrderUnit().equals("支")) {
            if (inEntity.getLengthMax() <= 0) {
                errMessage[0] = "合同长度上限必须大于零！";
                return false;
            }
            if (inEntity.getLengthMin() < 0) {
                errMessage[0] = "合同长度下限不能为负数！";
                return false;
            }
            if (inEntity.getLengthMax() < inEntity.getLengthMin()) {
                errMessage[0] = "合同长度上限不能小于下限！";
                return false;
            }
            if (inEntity.getOutdiameter() <= 0) {
                errMessage[0] = "合同外径必须大于零！";
                return false;
            }
            if (inEntity.getWallthick() <= 0) {
                errMessage[0] = "合同壁厚必须大于零！";
                return false;
            }
            if (inEntity.getOutdiameter() < inEntity.getWallthick()) {
                errMessage[0] = "合同外径不能小于壁厚！";
                return false;
            }
            if (inEntity.getDiameterZg() <= 0) {
                errMessage[0] = "轧管工序，轧管规格外径必须大于零！";
                return false;
            }
            if (inEntity.getHeightZg() <= 0) {
                errMessage[0] = "轧管工序，轧管规格壁厚必须大于零！";
                return false;
            }
            if (inEntity.getDiameterZg() < inEntity.getHeightZg()) {
                errMessage[0] = "轧管规格外径不能小于壁厚！";
                return false;
            }
            if (inEntity.getDiameterPl() == null
                    || inEntity.getDiameterPl().size() == 0) {
                errMessage[0] = "轧管工序，坯料断面规格未知！";
                return false;
            }
            else {
                for (int i = 0; i < inEntity.getDiameterPl().size(); i++) {
                    if (inEntity.getDiameterPl().get(i) <= 0) {
                        errMessage[0] = "轧管工序，坯料断面必须大于零！";
                        return false;
                    }
                }
            }
            if (inEntity.getCutHeadEnd() < 0) {
                errMessage[0] = "轧管工序，切头尾不能为负数！";
                return false;
            }
            if (inEntity.getLengthMaxRing() <= 0) {
                errMessage[0] = "轧管工序，坯料最长长度必须大于零！";
                return false;
            }
            if (inEntity.getLengthColdbed() <= 0) {
                errMessage[0] = "轧管工序，产线冷床长度必须大于零！";
                return false;
            }
            if (inEntity.getSigllen() < 0) {
                errMessage[0] = "单倍尺长不能为负数！";
                return false;
            }
            if (inEntity.getBurnoutRate() < 0
                    || inEntity.getBurnoutRate() > 100) {
                java.text.DecimalFormat df = new java.text.DecimalFormat(
                        "#0.00");
                errMessage[0] = "轧管烧损率有误，"
                        + df.format(inEntity.getBurnoutRate()) + "%。";
                return false;
            }
            if (inEntity.getFootmin() < 0) {
                errMessage[0] = "短尺最短不能为负数！";
                return false;
            }
            if (inEntity.getAddLengthDbk() < 0) {
                errMessage[0] = "镦拔扩加长值不能为负数！";
                return false;
            }
            if (inEntity.getAddLengthDc() < 0) {
                errMessage[0] = "镦粗影响长度值不能为负数！";
                return false;
            }
            if (inEntity.getBurnoutDbk() < 0 || inEntity.getBurnoutDbk() > 100) {
                java.text.DecimalFormat df = new java.text.DecimalFormat(
                        "#0.00");
                errMessage[0] = "镦拔扩烧损率有误，"
                        + df.format(inEntity.getBurnoutDbk()) + "%。";
                return false;
            }
            if (inEntity.getInspectLen() < 0) {
                errMessage[0] = "探伤盲区切长度值不能为负数！";
                return false;
            }
        }
        if (inEntity.getOrderUnit().equals("英磅")
                || inEntity.getOrderUnit().equals("吨")) {
            if (inEntity.getTotlength() == 0) {
                if (inEntity.getWeightType() != 0
                        && inEntity.getWeightType() != 1
                        && inEntity.getWeightType() != -1) {
                    errMessage[0] = "合同按重量交货，但未知计重方式！";
                    return false;
                }
            }
        }
        if (inEntity.getDelvryRangeMax() < 0
                || inEntity.getDelvryRangeMin() < 0) {
            errMessage[0] = "交货量差有误！";
            return false;
        }
        if (inEntity.getDelvryRangeTpe() != 1
                && inEntity.getDelvryRangeTpe() != 2) {
            errMessage[0] = "交货量差方式未知！";
            return false;
        }
        if (inEntity.getWeightJg() < 0) {
            errMessage[0] = "接箍单重不能为负数！";
            return false;
        }
        if (inEntity.getCheckJVal() < 0) {
            errMessage[0] = "接箍测量J值不能为负数！";
            return false;
        }
        return true;
    }

    /**
     * 管体米单重计算公式（t/m）
     * @param outdiameter (mm)
     * @param wallthick (mm)
     * @return
     */
    public static double tubeWeightMi(double outdiameter, double wallthick) {
        return 0.02466 * wallthick * (outdiameter - wallthick) / 1000;
    }

    /**
     * 轧管加长原则
     * @param lenMax 成品长度上限
     * @param lenMin 成品长度下限
     * @param modelDesc 扣型描述
     * @return mm
     */
    /*
     * public static double addLenZgRule(double lenMax, double lenMin, String
     * modelDesc){ double addlen = 0; if ((modelDesc.contains("PE") ||
     * modelDesc.contains("BE")) && (lenMax - lenMin) < 0.3) { addlen = 0.3 /
     * (int) (14.5 / lenMax); } return addlen * 1000; }
     *//**
     * 轧管加长原则（长度上限）
     * @param lenMax 成品长度上限
     * @param lenMin 成品长度下限
     * @param modelDesc 扣型描述
     * @return mm
     */
    /*
     * public static double addLenZgRuleMax(double lenMax, double lenMin, String
     * modelDesc) { double addlen = 0; if (lenMax <= 7) { if
     * ((modelDesc.contains("PE") || modelDesc.contains("BE")) && (lenMax -
     * lenMin) < 0.3) { addlen = 0.2; } } else { if ((modelDesc.contains("PE")
     * || modelDesc.contains("BE")) && (lenMax - lenMin) < 0.3) { addlen = 0.4;
     * } } return addlen * 1000; }
     *//**
     * 轧管加长原则（长度下限）
     * @param lenMax 成品长度上限
     * @param lenMin 成品长度下限
     * @param modelDesc 扣型描述
     * @return mm
     */
    /*
     * public static double addLenZgRuleMin(double lenMax, double lenMin, String
     * modelDesc) { double addlen = 0; if (lenMax <= 7) { if
     * ((modelDesc.contains("PE") || modelDesc.contains("BE")) && (lenMax -
     * lenMin) < 0.3) { addlen = 0.1; } } else { if ((modelDesc.contains("PE")
     * || modelDesc.contains("BE")) && (lenMax - lenMin) < 0.3) { addlen = 0.2;
     * } } return addlen * 1000; }
     */
}