/// 
///LOGIC CLASS FOR TABLE t_wmsInRequest
///By wm with codesmith. 
///on 05/12/2017
/// 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DeiNiu.wms.Data.Model;
using System.Data;
using System.Transactions;
using DeiNiu.Data.BaseObject;
using DeiNiu.Utils;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Net;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
//using Microsoft.Reporting.WinForms;
namespace DeiNiu.wms.Logical
{
    [Serializable]
    public class lWmsInRequest : lbase
    {
        WmsInRequest _obj;
        WmsStock _stkObj;
        //  private int p;
        Erp_purch _erpPurchObj;
        Erp_purch_ship _erpPurchShipObj;
        Erp_purch_receive_pre _preInObj = new Erp_purch_receive_pre();
        public Erp_purch_receive_pre preInObj
        {
            get
            {
                if (_preInObj == null)
                {
                    _preInObj = new Erp_purch_receive_pre();
                    _preInObj.operater = this.operId;
                }
                return _preInObj;
            }
        }
        public Erp_purch_ship erpPurchShipObj
        {
            get
            {
                if (_erpPurchShipObj == null)
                {
                    _erpPurchShipObj = new Erp_purch_ship();
                    _erpPurchShipObj.operater = this.operId;
                }
                return _erpPurchShipObj;
            }
        }
        public WmsStock stkObj
        {
            get
            {
                if (_stkObj == null)
                {
                    _stkObj = new WmsStock();
                    _stkObj.operater = this.operId;
                }
                return _stkObj;
            }
        }
        public Erp_purch erpPurchObj
        {
            get
            {
                if (_erpPurchObj == null)
                {
                    _erpPurchObj = new Erp_purch();
                    _erpPurchObj.operater = this.operId;
                }
                return _erpPurchObj;
            }
        }
        public lWmsInRequest()
        {
            initialize();
        }
        public lWmsInRequest(int p) : base(p)
        {
            initialize();
        }
        public WmsInRequest getWmsInRequest
        {
            get
            {
                if (_obj == null)
                {
                    _obj = new WmsInRequest();
                    _obj.operater = this.operId;
                }
                return _obj;
              
            }
        }
        /// 
        /// get all data
        /// 
        public DataSet getAllData()
        {
            return _obj.Query();
        }
        /// 
        /// get all data
        /// 
        public DataSet getAllActiveData()
        {
            return _obj.QueryActived();
        }
        protected override BaseModel getModel()
        {
            return _obj;
        }
        /// 
        /// get a record by id
        /// 
        public void initialize(int id)
        {
            _obj = id != 0 ? new WmsInRequest(id) : new WmsInRequest();
        }
        /// 
		/// get a record by id 0
		/// 
        public void initialize()
        {
            initialize(0);
        }
        /// 
        /// get a record by id
        /// 
        public void initialize(DataRow dr)
        {
            _obj = new WmsInRequest(dr);
        }
        //begin cust db operation, query, excute sql etc.
        /// 
        /// get in_stock request in a transaction scope
        /// 
        public void syncOrders()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                _obj.syncInRequest();
                scope.Complete();
            }
        }
        private bool valid()
        {
            return true;
        }
        public bool requestInStock(string orderNo)
        {
            return requestInStock(new WmsInRequest(orderNo));
        }
        public bool requestInStock(WmsInRequest requestOrder)
        {
            // printStockIn(orderNo);
            requestOrder.operater = this.operId;
            if (requestOrder.ID == 0)
            {
                return false;
                //throw new DeiNiuException(requestOrder.orderNo + " 不存在");
            }
            if (requestOrder.state == (int)enumInStockOrderStatus.已入库)
            {
                return false;
                // throw new DeiNiuException(requestOrder.orderNo + " 已经入库");
            }
            //入库前检查产品生产日期,有效期
            bool isDateInvalid = false;
            foreach (WmsInRequestDetail requestDetail in requestOrder.inDetails)
            {
                if (requestDetail.state == (int)enumInStockDetailStatus.已分配货位)
                {
                    continue;
                }
                if (requestDetail.whType == (int)enumWhType.不合格库)
                {
                    continue;
                }
                requestDetail.operater = this.operId;
                if (!checkAndUpdateValidDate(requestDetail)) //生产日期,有效期错误
                {
                    isDateInvalid = true;
                    requestDetail.state = (int)enumInStockDetailStatus.日期错误;
                    requestDetail.Update();
                }
            }
            if (isDateInvalid)
            {
                requestOrder.state = (int)enumInStockOrderStatus.订单明细日期错误;
                requestOrder.Update();
                return false;
            }
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions()
            {
                IsolationLevel = System.Transactions.IsolationLevel.Serializable,
                Timeout = new TimeSpan(0, 10, 0)
            }
                  ))
            {
                foreach (WmsInRequestDetail requestDetail in requestOrder.inDetails)
                {
                    if (requestDetail.state == (int)enumInStockDetailStatus.已分配货位)
                    {
                        continue;
                    }
                    requestDetail.operater = this.operId;
                    try
                    {
                        requestDetailIn(requestOrder, requestDetail);
                    }
                    catch (DeiNiuNoFreeLocationkException nfe)
                    {
                        scope.Dispose();
                        requestDetail.state = (int)enumInStockDetailStatus.货位不足; ;
                        requestDetail.description = nfe.Message;
                        requestDetail.Update();
                        requestOrder.state = (int)enumInStockOrderStatus.货位不足;
                        requestOrder.Update();
                        throw nfe;
                    }
                    catch (DeiNiuException er)
                    {
                        scope.Dispose();
                        requestDetail.state = (int)enumInStockDetailStatus.出现错误; ;
                        requestDetail.description = er.Message;
                        requestDetail.Update();
                        requestOrder.state = (int)enumInStockOrderStatus.待上架;
                        requestOrder.Update();
                        throw er;
                    }
                    catch (Exception err)
                    {
                        throw err;
                    }
 
                }
                requestOrder.state = (int)enumInStockOrderStatus.已入库;
                requestOrder.Update();
                if (!WmsConstants.IN_STOCK_RECEIVE_VALID) //不启用验收模块,则一次入库完毕。
                {
                    erpPurchObj.updateStockStatus(requestOrder.preInOrder, enumInStockOrderStatus.已入库,
                        enumReceiveStockDetailStatus.待上架, operId);
                }
                else
                {
                    string lastOrder = "";
                    foreach (WmsInRequestDetail requestDetail in requestOrder.inDetails)
                    {
                        if (requestDetail.orderNo.Equals(lastOrder))
                        {
                            continue;
                        }
                        Erp_purch ep = new Erp_purch(requestDetail.orderNo);
                        if (ep.wms_state == (int)enumInStockOrderStatus.已验收) //入库单明细全部完成验收后
                        {
                            ep.wms_state = (int)enumInStockOrderStatus.已入库;
                            ep.Update();
                        }
                        lastOrder = requestDetail.orderNo;
                    }
                }
                //  Erp_purch_d epd = new Erp_purch_d();
                scope.Complete();
            }
            //if (requestOrder.orderType == (int)enumInOrderType.purOrder)
            //{
            //    // printStockIn(requestOrder.orderNo);
            //}
            return true;
        }
        internal DataSet queryStockInSum(string querystr, int rownumStart, int rownumEnd)
        {
            return getWmsInRequest.queryStockInSum(querystr,  rownumStart,  rownumEnd);
        }
        public DataTable getPreValidResult(string preInNo)
        {
          return   erpPurchObj.getPreValidResult( preInNo);
        }
        private void requestDetailIn(WmsInRequest requestOrder, WmsInRequestDetail requestDetail, int recommandWareHouse = 0, bool isOnce = false)
        {
            enumWhType whType = (enumWhType)requestDetail.whType;
            logIn.Debug(string.Format("requestDetailIn whType {0}",whType.ToString()));
            if (whType == enumWhType.越仓收货区)
            {
                zhitongIn(requestDetail,isOnce);
            }
            else if (whType == enumWhType.虚拟库)
            {
                requestDetail.state = (int)enumInStockDetailStatus.上架完成;
                requestDetail.countIn = requestDetail.validCount;
                requestDetail.Update();
                logStock(requestDetail, new WmsStock().getVirStock(requestDetail.goodsId), requestDetail.validCount, enumInStoreType.虚拟入库冲抵);
                 updateErpDetail(requestDetail);
           } 
            else if (goodsInStock(requestDetail, recommandWareHouse))
            {
                if (whType == enumWhType.不合格库)
                {
                    //Wmslocation location = new Wmslocation();
                    // List locs = location.geLocations(enumWhType.不合格库);
                    requestDetail.state = (int)enumInStockDetailStatus.入不合格区;
                    requestDetail.description = "已入不合格区";
                    requestDetail.Update();
                }
                else
                {
                    requestDetail.state = (int)enumInStockDetailStatus.已分配货位;
                    requestDetail.countIn = requestDetail.validCount;
                    requestDetail.Update();
                }
                updateErpDetail(requestDetail);
            }
            else //if(WmsConstants.IN_STOCK_ONE_TIME)
            {
                throw new DeiNiuException("入库异常");
            }
        }
        private void zhitongIn(WmsInRequestDetail requestDetail, bool isOnce = false)
        {
            logIn.Debug(" zhitong in " + requestDetail);
            WmsStockPre wsp = new WmsStockPre();
            wsp.orderno = requestDetail.orderNo;
            wsp.orderDetailId = requestDetail.ID;
            wsp.partion = requestDetail.partion;
            wsp.skuCode = requestDetail.skuCode;
            wsp.skuId = requestDetail.skuId;
            wsp.batch = requestDetail.batch;
            wsp.productDate = requestDetail.productDate;
            wsp.validDate = requestDetail.validDate;
            wsp.count = requestDetail.validCount;
            wsp.goodsId = requestDetail.goodsId;
            wsp.Add();
            requestDetail.countIn = requestDetail.validCount;
            updateErpDetail(requestDetail);
            if (requestDetail.outDetailId > 0)
            {
                requestDetail.state = (int)enumInStockDetailStatus.直通分货完成;
                requestDetail.description = "完成收货";
                zhiTongSeedOut(requestDetail.outDetailId, requestDetail.ID, requestDetail.countIn, requestDetail.flowNo,isOnce);
                //  logStock(requestDetail, null, wsp.count, enumInStoreType.直通越仓, wsp);
                logStock(requestDetail, null, wsp.count, enumInStoreType.直接上架, wsp);
            }
            else
            {
                requestDetail.state = (int)enumInStockDetailStatus.入越仓收货区;
                requestDetail.description = "已入越库区,等待分播到店";
                logStock(requestDetail, null, wsp.count, enumInStoreType.直通越仓, wsp);
            }
       
            requestDetail.Update();
        }
        /// 
        /// 更新入库数据
        /// 
        /// 
        /// 
        bool updateErpDetail(WmsInRequestDetail requestDetail)
        {
            if (!WmsConstants.IN_STOCK_RECEIVE_VALID)
            {
                return false;
            }
          
            DataTable dt = erpPurchObj.getValidedInDetail(requestDetail.orderNo, (int)enumReceiveStockDetailStatus.已验收);
            decimal inCnt = requestDetail.validCount;//.countIn;
            foreach (DataRow dr in dt.Rows)
            {
                Erp_receiveValidDetail evd = new Erp_receiveValidDetail(dr);
                if (evd.goods_id == requestDetail.goodsId
                    && evd.batch == requestDetail.batch
                    && evd.productDate == requestDetail.productDate
                    && evd.validDate == requestDetail.validDate)
                {
                    evd.inCount = evd.valid_count < inCnt ? evd.valid_count : inCnt;
                    inCnt -= evd.inCount;
                    evd.operater = this.operId; 
                    evd.wms_state = (int)enumReceiveStockDetailStatus.待上架;
                  if(  requestDetail.state ==(int)enumInStockDetailStatus.上架完成)
                    {
                        evd.upShelfCount = evd.valid_count;
                        evd.wms_state = (int)enumReceiveStockDetailStatus.已上架;
                    }
                  
                    evd.Update();
                }
                if (inCnt <= 0)
                {
                    break;
                }
            }
            return true;
        }
        /// 
        /// 更新上架数据
        /// 
        /// 
        /// 
        bool updateErpDetail(int detailId)
        {
            LogHelper.debug(GetType(), "updateErpDetail ? " + detailId);
            WmsInRequestDetail requestDetail = new WmsInRequestDetail(detailId);
            decimal upShelfCnt = requestDetail.countIn;//.countIn;
                                                       // DataTable dt = erpPurchObj.getValidedInDetail(requestDetail.orderNo, (int)enumReceiveStockDetailStatus.待上架);
            Erp_receiveValidDetail evd = new Erp_receiveValidDetail(requestDetail.validId);
            evd.upShelfCount += upShelfCnt;
            evd.operater = this.operId;
            evd.wms_state = (int)enumReceiveStockDetailStatus.已上架;
            evd.Update();
            LogHelper.debug(GetType(), "updateErpDetail ?   upShelfCnt is " + upShelfCnt + ", erp_receiveValidDetail updated ");
            new Erp_purch_receive_pre().upShelfCount(evd.preInOrder, requestDetail.purch_d_id, upShelfCnt, operId);
            /*
             DataTable dt = new Erp_receiveValidDetail().getDetailByFlowNo(requestDetail.preInOrder, requestDetail.flowNo);
             DataView dv = dt.DefaultView;
             dv.RowFilter = "skuId=" + requestDetail.skuId;
             LogHelper.debug(GetType(), "updateErpDetail ?  filter by skuId" + requestDetail.skuId +", erp_receiveValidDetail count is " + dv.Count);
             decimal upShelfCnt = requestDetail.countIn;//.countIn;
             foreach (DataRowView dr in dv)
             {
                 Erp_receiveValidDetail evd = new Erp_receiveValidDetail(dr.Row);
                  //   evd.upShelfCount = evd.inCount < upShelfCnt ? evd.inCount : upShelfCnt;
                     evd.upShelfCount += upShelfCnt;
                    // upShelfCnt -= evd.inCount;
                     evd.operater = this.operId;
                     evd.wms_state = (int)enumReceiveStockDetailStatus.已上架;
                     evd.Update();
                     LogHelper.debug(GetType(), "updateErpDetail ?   upShelfCnt is " + upShelfCnt  + ", erp_receiveValidDetail updated ");
                     new Erp_purch_receive_pre().upShelfCount(evd.preInOrder, requestDetail.purch_d_id, upShelfCnt, operId);
             } 
              * */
            /// WmsInRequest wir  = new WmsInRequest(requestDetail.orderNo);
            Erp_purch_d epd = new Erp_purch_d(requestDetail.purch_d_id);
            epd.onShelfCount += upShelfCnt;
            if (epd.onShelfCount >= epd.validCount && epd.wms_state == (int)enumReceiveStockDetailStatus.已验收)
            {
                epd.wms_state = (int)enumReceiveStockDetailStatus.已上架;
            }
            epd.operater = operId;
            epd.Update();
            DataTable dtDetails = erpPurchObj.getOrderDetail(requestDetail.orderNo);
            DataView dvDetail = dtDetails.DefaultView;
            dvDetail.RowFilter = "wms_state<" + (int)enumReceiveStockDetailStatus.已上架;
            if (dvDetail.Count == 0)
            {
                _erpPurchObj = new Erp_purch(requestDetail.orderNo);
                if (_erpPurchObj.wms_state < (int)enumInStockOrderStatus.已上架)
                {
                    _erpPurchObj.wms_state = (int)enumInStockOrderStatus.已上架;
                    _erpPurchObj.operater = operId;
                    _erpPurchObj.Update();
                }
            }
            // erpPurchObj.updateStockStatus(requestDetail.orderNo, (enumInStockOrderStatus)wir.state, enumReceiveStockDetailStatus.已上架, operId);
            /*
            if(wir.state ==  (int)enumInStockOrderStatus.已上架 ){ 
           
                erpPurchObj.updateStockStatus(requestDetail.orderNo, enumInStockOrderStatus.已上架, enumReceiveStockDetailStatus.已上架,operId);
            }
            */
            /*
             dt = erpPurchObj.getValidedInDetail(requestDetail.orderNo, (int)enumReceiveStockDetailStatus.待上架);
             if (dt.Rows.Count == 0)
             {
                 _erpPurchObj = new Erp_purch(requestDetail.orderNo);
                 erpPurchObj.wms_state = (int)enumInStockOrderStatus.已上架;
                 erpPurchObj.Update();
             }
             */
            return true;
        }
        bool checkAndUpdateValidDate(WmsInRequestDetail requestDetail)
        {
            string productDate = requestDetail.productDate.Trim();
            string validDate = requestDetail.validDate.Trim();
            string[] invailidChars = { ".", "-", "/" };
            foreach (string s in invailidChars)
            {
                if (WmsConstants.GOODS_VALID_DATE_FORMAT.IndexOf(s) == -1)
                {
                    productDate = productDate.Replace(s, "");
                    validDate = validDate.Replace(s, "");
                }
            }
            if (productDate.Length < 6 || productDate.Length > 8 || validDate.Length < 6 || validDate.Length > 8)
            {
                if (WmsConstants.IN_STOCK_CHECK_DATE)
                {
                    return false;
                }
            }
            productDate += productDate.Length == 6 ? "28" : "";
            validDate += validDate.Length == 6 ? "01" : "";
            DateTime dtprd, dtvlid;
            try
            {
                dtprd = DateTime.ParseExact(productDate, WmsConstants.GOODS_VALID_DATE_FORMAT, System.Globalization.CultureInfo.CurrentCulture);
                dtvlid = DateTime.ParseExact(validDate, WmsConstants.GOODS_VALID_DATE_FORMAT, System.Globalization.CultureInfo.CurrentCulture);
                if (WmsConstants.IN_STOCK_CHECK_DATE && dtvlid <= DateTime.Now)
                {
                    requestDetail.description = "产品过期";
                    return false;
                }
                requestDetail.productDate = dtprd.ToString(WmsConstants.GOODS_VALID_DATE_FORMAT);
                requestDetail.validDate = dtvlid.ToString(WmsConstants.GOODS_VALID_DATE_FORMAT);
            }
            catch
            {
                if (WmsConstants.IN_STOCK_CHECK_DATE)
                {
                    return false;
                }
            }
            requestDetail.state = (int)enumInStockDetailStatus.未分配货位;
            requestDetail.Update();
            return true;
        }
        //TODO: 调整 可空货位优先
        /// 
        /// 分配货位入库
        /// 1.整货入整库,整库不能进零货
        ///2. WmsConstants.IN_STOCK_CHECK_BULK_FIRST = true: 商品在零库已有零货位存在的情况下,优先补足零货
        /// 
        /// 
        /// 
        private bool goodsInStock(WmsInRequestDetail requestDetail, int recommandWareHouse = 0)
        {
          logIn.Debug( string.Format("goodsInStock request order {0},detail id {1},count{2}"
                                                , requestDetail.orderNo, requestDetail.ID, requestDetail.orderCount)); 
            logIn.Debug(string.Format("goodsInStock requestDetail is {0}", requestDetail.ToString()));
            decimal count = requestDetail.validCount - requestDetail.countIn;
            if (count <= 0)
            {
                return true;
            }
            // WmsGoods goods = ObjectsFactory.getGoods(requestDetail.goodsId, requestDetail.skuId, requestDetail.batch,true);//new WmsGoods(requestDetail.goodsId);
            WmsGoods goods = new WmsGoods(requestDetail.goodsId, requestDetail.skuId, requestDetail.batch);
            WmsStock stock = new WmsStock();
            decimal bulkCnt = 0;
            decimal batch1Cnt = 0;
            decimal batch2Cnt = 0;
            decimal batch3Cnt = 0;
            Dictionary locs2add = new Dictionary();
            Dictionary locsUpdate = new Dictionary();
            int goodType = goods.goodsType;
            string goodsId = goods.goodsId;
            string batch = requestDetail.batch;
            int skuId = requestDetail.skuId;
            string skuCode = requestDetail.skuCode;
            if (skuId > 0 && string.IsNullOrEmpty(skuCode))
            {
                Sku sku = new Sku(skuId);
                if (sku.ID > 0)
                {
                    requestDetail.skuCode = skuCode = sku.skuCode;
                }
            }
            logIn.Debug("requestDetail json -->" + Util.getJson(requestDetail));
            if (requestDetail.whType == (int)enumWhType.不合格库)
            {
                WmsLocation nearLoc = new WmsLocation();
                nearLoc.volType = (int)enumWhLocVol.不合格区;
                List locs = null;
                int cnt = 1;
               
                logIn.Debug(string.Format("需 {0} 型新库位 {1}", enumWhLocVol.不合格区, cnt));
                try
                {
                    locs = nearLoc.getFreeLocation(nearLoc, (enumWhType)requestDetail.whType, cnt);
                    logIn.Debug(string.Format(" 找到 {0} 型新库位 {1}", enumWhLocVol.不合格区, locs.Count));
                    foreach (WmsLocation loc in locs)
                    {
                        locs2add.Add(loc,requestDetail.validCount); 
                    } 
                  
                  
                }
                catch (DeiNiuNoFreeLocationkException er) //小整货位不足
                {
                    logIn.Debug(string.Format(" 没有找到新库位。。。。"));
                    
                    if(locs2add.Count == 0)
                    {
                        nearLoc.locationId = "临时货位";
                        locs2add.Add(nearLoc, requestDetail.validCount);
                    }
                }
            }else
            {  
            decimal bigCount = goods.bigCount;
            //decimal boxCount = 0; //箱数
          
            decimal bulkCntFromBatch = 0;
            decimal bulkMax = goods.bulkMax;
            decimal batchMax1 = goods.batchMax1;
            decimal batchMax2 = goods.batchMax2;
            decimal batchMax3 = goods.batchMax3;
            // decimal stockCnt =0;
            if (bigCount == 0)
            {
                throw new DeiNiuException(string.Format("请维护 '{0}' 的大包装数量, pickdetailid {1}", requestDetail.goodsId, requestDetail.ID));
            }
            if (goodType == 0)
            {
                throw new DeiNiuException(string.Format("请维护 '{0}' 的商品类型", requestDetail.goodsId));
            }
            //现在默认  每种商品 在零货位上的最大容量为 1.3箱    小整4箱  大整  20
            //一箱 是指一个大包装量(erp bigCount)
            bulkMax = bulkMax > 0 ? bulkMax : bigCount * WmsConstants.BULK_MAX_RATE;
            batchMax1 = batchMax1 > 0 ? batchMax1 : bigCount * WmsConstants.BATCH1_MAX_RATE;
            batchMax2 = batchMax2 > 0 ? batchMax2 : bigCount * WmsConstants.BATCH2_MAX_RATE;
            batchMax3 = batchMax3 > 0 ? batchMax3 : bigCount * WmsConstants.BATCH3_MAX_RATE;
            //boxCount =  count / bigCount ;
            decimal boxcnt = 0m;
            //  boxcnt = Math.Floor(count / bigCount);   
            //  bulkCnt = count - boxcnt * bigCount;
            bulkCnt = count % bigCount;  //取余数,不足箱部分
            count -= bulkCnt;
            count = count > 0 ? count : 0;
            if (count > 0)
            {
                logIn.Debug(string.Format("零库入数量:{0}, 整库入库数量:{1}, 是否优先入零库 :{2},goods.bulkMax:{3}", bulkCnt + "", count + "", WmsConstants.IN_STOCK_CHECK_BULK_FIRST, goods.bulkMax + ""));
                if (WmsConstants.IN_STOCK_CHECK_BULK_FIRST
                      && goods.bulkMax >= 0  //只有对设置零库库容的商品有效
                      && WmsConstants.IN_STOCK_DIFF_PARTS //零库、整库不同区的情况下是否允许跨区入库
                      && bulkCnt < goods.bulkMax
                     )
                {
                    decimal tmp = 0m;
                    //优先补足零库
                    DataTable dt0;
                    //  dt0 =   stock.queryByGoodsIdVolType(skuId,skuCode,goods.goodsId, requestDetail.batch, enumWhLocVol.零库, enumWhType.合格库);
                    dt0 = stock.queryByGoodsIdVolType(0, "", goods.goodsId, requestDetail.batch, enumWhLocVol.零库,
                        (enumWhType)requestDetail.whType);//库容按商品ID,不是按skuId
                    //计算补零货数
                    foreach (DataRow dr in dt0.Rows)
                    {
                        stock = new WmsStock(dr);
                        decimal onShelfCnt = stock.count - stock.countOut;
                        onShelfCnt = onShelfCnt > 0 ? onShelfCnt : 0;
                        tmp += onShelfCnt;// - stock.countLock; 
                        if (WmsConstants.IN_STOCK_PDA_SCAN)
                        {
                            tmp += stock.countIn;
                        }
                    }
                    decimal diff = bulkMax - tmp;
                    logIn.Debug(string.Format("零库存:{0}, 补零数量{1}", tmp + "", diff + ""));
                    if (diff > 0) //需要补
                    {
                        if (diff >= bulkCnt) //需要拆箱补货
                        {
                            if (WmsConstants.IN_STOCK_DIFF_PARTS) //同一组验收数量可进不同货区
                            {
                                decimal cnt = Math.Ceiling((diff - bulkCnt) / bigCount) * bigCount;
                                cnt = cnt > count ? count : cnt;
                                bulkCnt += cnt;
                                count -= cnt;
                            }
                        }
                    }
                    /* 
                    bulkCnt +=   tmp  >= bulkMax ? 0  //零库充足,不补
                        : bulkMax - (tmp + bulkCnt) ;          //补充部分 
                    bulkCnt = Math.Ceiling(bulkCnt / bigCount) * bigCount; //成箱补充 
                    bulkCnt = bulkCnt > count ? count : bulkCnt;
                    count = count - bulkCnt;
                    count = count > 0 ? count : 0;
                    */
                }
            }
            boxcnt = Math.Floor(count / bigCount);
            if (count > batchMax1) //入整库
            {
                if (count > batchMax2)
                {
                    batch3Cnt = count;
                }
                else
                {
                    batch2Cnt = count;
                }
            }
            else
            {
                batch1Cnt = count;
            }
            logIn.Debug(string.Format("入库数量 大整:{0},小整:{1},零货:{2},超大整{3}", batch2Cnt, batch1Cnt, bulkCnt, batch3Cnt));
            /*
            if (orderType == enumInOrderType.repOrderIn) //处理补零入库单
            {
                batch1Cnt = 0;
                batch2Cnt = 0;
                bulkCnt = requestDetail.validCount - requestDetail.countIn;
                 
            } 
            */
            DataTable dt = stock.querySameGoodsLocations(goods.goodsId, enumWhLocVol.通用, skuId, requestDetail.batch
                , (enumWhType)requestDetail.whType, recommandWareHouse);
            
            Dictionary locsBulk = new Dictionary();
            Dictionary locsBatch1 = new Dictionary();
            Dictionary locsBatch2 = new Dictionary();
            Dictionary locsBatch3 = new Dictionary();
            string lastBatch3Location = "";
            string lastBatch2Location = "";
            string lastBatch1Location = "";
            string lastBulkLocation = "";
            string lastLoc = "";
            //计算补货货位及数量
            logIn.Debug(string.Format("计算补货货位及数量,现有库存记录数量:{0}", dt.Rows.Count));
            foreach (DataRow dr in dt.Rows)
            {
                if (batch2Cnt + batch1Cnt + bulkCnt + batch3Cnt == 0)
                {
                    break;
                }
                // logIn.Debug(" 待人总数量 :  " + (batch2Cnt + batch1Cnt + bulkCnt + batch3Cnt));
                logIn.Debug(string.Format(" 现有库存货位 待人总数量 {4} : 超大整: {3}, 大整: {0}, 小整: {1}, 零货: {2},", batch2Cnt, batch1Cnt, bulkCnt, batch3Cnt, (batch2Cnt + batch1Cnt + bulkCnt + batch3Cnt)));
                stock = new WmsStock(dr);
                if (lastLoc == "")
                {
                    lastLoc = stock.locationId;
                }
                else
                    if (lastLoc.Equals(stock.locationId))
                {
                    continue;
                }
                lastLoc = stock.locationId;
                int locVolType = Convert.ToInt32(dr[WmsLocation.fields.volType.ToString()].ToString());
                enumWhLocVol volType = (enumWhLocVol)locVolType;
                // check if continue
                switch (volType)
                {  //当前货位类型
                    case enumWhLocVol.零库:
                        lastBulkLocation = stock.locationId;
                        if (bulkCnt == 0)
                        {
                            continue;
                        }
                        break;
                    case enumWhLocVol.小整:
                        lastBatch1Location = stock.locationId;
                        if (batch1Cnt == 0)
                        {
                            continue;
                        }
                        break;
                    case enumWhLocVol.中整:
                        lastBatch2Location = stock.locationId;
                        if (batch2Cnt == 0)
                        {
                            if (batch1Cnt <= 0
                                || !WmsConstants.IN_STOCK_BIG_LOCATION_FIRST)//优先补大货位
                            {
                                continue;
                            }
                        }
                        break;
                    case enumWhLocVol.大整:
                        lastBatch3Location = stock.locationId;
                        if (batch3Cnt == 0)
                        {
                            if (batch2Cnt <= 0
                                || !WmsConstants.IN_STOCK_BIG_LOCATION_FIRST)//优先补大货位
                            {
                                continue;
                            }
                        }
                        break;
                }
                if (WmsConstants.IN_STOCK_ABC && stock.location.ABC != goods.ABC) {
                    continue;
                }
                enumWhLocStoreType stype = (enumWhLocStoreType) Convert.ToInt32(dr["storeType"].ToString());
                switch (stype)
                {
                    case enumWhLocStoreType.同品同批:
                        if (stock.batch != batch || stock.skuId != skuId)
                        {
                            continue;
                        }
                        break;
                    case enumWhLocStoreType.混品同批:
                        if (stock.batch != batch )
                        {
                            continue;
                        }
                        break;
                     case enumWhLocStoreType.混品混批:
                            
                            break;
                    }
                decimal existCnt = stock.count + stock.countIn - stock.countOut;// -stock.countOuting;// - stock.countLock;
                existCnt = existCnt > 0 ? existCnt : 0;
                LogHelper.debug(this.GetType(), string.Format("现有库存 {0}, skuid {1}, 数量{2}", stock.locationId, stock.skuId, existCnt));
                decimal goodsMaxcnt = goods.getMaxCount(locVolType);
                decimal freeCntCapicity = Math.Ceiling((1 - stock.getUsedPercent(lastLoc)) * goodsMaxcnt);
                LogHelper.debug(this.GetType(), string.Format("库位类型{1},可用容量 {0} ", freeCntCapicity, volType));
                if (freeCntCapicity <= 0)
                {
                    continue;
                }
                switch (volType)
                {  //当前货位类型
                    case enumWhLocVol.零库:
                        lastBulkLocation = stock.locationId;
                        if (bulkCnt == 0)
                        {
                            continue;
                        }
                        if (bulkCnt <= freeCntCapicity)
                        {
                            locsUpdate.Add(new WmsStock(stock.locationId, stock.skuId, stock.goodsId), bulkCnt);
                            bulkCnt = 0;
                        }
                        else
                        {
                            locsUpdate.Add(new WmsStock(stock.locationId, stock.skuId, stock.goodsId), freeCntCapicity);
                            bulkCnt -= freeCntCapicity;
                        }
                        break;
                    case enumWhLocVol.小整:
                        lastBatch1Location = stock.locationId;
                        if (batch1Cnt == 0)
                        {
                            continue;
                        }
                        if (batch1Cnt <= freeCntCapicity)
                        {
                            locsUpdate.Add(new WmsStock(stock.locationId, stock.skuId, stock.goodsId), batch1Cnt);
                            batch1Cnt = 0;
                        }
                        else
                        {
                            decimal buchongCount = Math.Floor(freeCntCapicity / bigCount) * bigCount;//补整箱
                            locsUpdate.Add(new WmsStock(stock.locationId, stock.skuId, stock.goodsId), buchongCount);
                            batch1Cnt -= buchongCount;
                        }
                        break;
                    case enumWhLocVol.中整:
                        lastBatch2Location = stock.locationId;
                        if (batch2Cnt == 0)
                        {
                            if (batch1Cnt <= 0
                                || !WmsConstants.IN_STOCK_BIG_LOCATION_FIRST)//优先补大货位
                            {
                                continue;
                            }
                        }
                        if (existCnt < goodsMaxcnt) //补充货位
                        {
                            lastBatch2Location = stock.locationId;
                            decimal maxCount = goodsMaxcnt - existCnt;
                            maxCount = Math.Floor(maxCount / bigCount) * bigCount;//补整箱
                            decimal buchongCount = maxCount;// -batch2Cnt;
                            if (batch2Cnt >= maxCount) // 需要新货位
                            {
                                batch2Cnt -= maxCount; //补现有货位后,剩余的入新货位 
                            }
                            else  //大整数量全部补充货位
                            {
                                buchongCount = batch2Cnt;// maxCount - batch2Cnt;
                                if (batch1Cnt > 0 && WmsConstants.IN_STOCK_BIG_LOCATION_FIRST) //优先补大货位
                                {
                                    if (batch1Cnt > maxCount - buchongCount) //小整补完大整货位仍有余
                                    {
                                        batch1Cnt -= maxCount - buchongCount;
                                        buchongCount = maxCount;
                                    }
                                    else //小整全部补大整
                                    {
                                        //  maxCount = batch1Cnt + batch2Cnt;
                                        buchongCount = batch1Cnt + batch2Cnt;
                                        batch1Cnt = 0;
                                    }
                                }
                                batch2Cnt = 0;
                            }
                            // locsBatch2.Add(new WmsStock(stock.locationId), c);
                            locsUpdate.Add(new WmsStock(stock.locationId, stock.skuId, stock.goodsId), buchongCount);
                        }
                        break;
                    case enumWhLocVol.大整:
                        lastBatch3Location = stock.locationId;
                        if (batch3Cnt == 0)
                        {
                            if (batch2Cnt <= 0
                                || !WmsConstants.IN_STOCK_BIG_LOCATION_FIRST)//优先补大货位
                            {
                                continue;
                            }
                        }
                        if (existCnt < goodsMaxcnt) //补充货位
                        {
                            lastBatch3Location = stock.locationId;
                            decimal maxCount = goodsMaxcnt - existCnt;
                            maxCount = Math.Floor(maxCount / bigCount) * bigCount;//补整箱
                            decimal buchongCount = maxCount;// -batch2Cnt;
                            if (batch3Cnt >= maxCount) // 需要新货位
                            {
                                batch3Cnt -= maxCount; //补现有货位后,剩余的入新货位 
                            }
                            else  //大整数量全部补充货位
                            {
                                buchongCount = batch3Cnt;// maxCount - batch2Cnt;
                                if (batch2Cnt > 0 && WmsConstants.IN_STOCK_BIG_LOCATION_FIRST) //优先补大货位
                                {
                                    if (batch2Cnt > maxCount - buchongCount) //小整补完大整货位仍有余
                                    {
                                        batch2Cnt -= maxCount - buchongCount;
                                        buchongCount = maxCount;
                                    }
                                    else //小整全部补大整
                                    {
                                        //  maxCount = batch1Cnt + batch2Cnt;
                                        buchongCount = batch2Cnt + batch3Cnt;
                                        batch2Cnt = 0;
                                    }
                                }
                                batch3Cnt = 0;
                            }
                            // locsBatch2.Add(new WmsStock(stock.locationId), c);
                            locsUpdate.Add(new WmsStock(stock.locationId, stock.skuId, stock.goodsId), buchongCount);
                        }
                        break;
                }
                //  stockCnt += cnt;
            }
            logIn.Debug(string.Format("需新库位: 大整:{0},小整:{1},零货:{2},超大整{3}", batch2Cnt, batch1Cnt, bulkCnt, batch3Cnt));
            logIn.Debug("开始计算新库位....");
            //入大整
            bool isBatchException = false;
            WmsLocation nearLocation = new WmsLocation();
            //  nearLocation.warehouse = recommandWareHouse;
            nearLocation.goodsType = goods.goodsType;
            nearLocation.warehouse = goods.part;
            nearLocation.ABC = goods.ABC;
            nearLocation.ownerCode = requestDetail.entid;// goods.ownerCode; //可能多货主共享商品id
         
            int locCnt = 1;
            if (batch3Cnt > 0)
            {
                nearLocation.locationId = lastBatch3Location;
                decimal cnt = batch3Cnt / batchMax3;
                locCnt = (int)Math.Ceiling(cnt);//有余数则会进一位
                nearLocation.volType = (int)enumWhLocVol.大整;
                logIn.Debug(string.Format("需 {0} 型新库位 {1}", enumWhLocVol.大整, locCnt));
                List locs = null;
                try
                {
                    locs = nearLocation.getFreeLocation(nearLocation, (enumWhType)requestDetail.whType, locCnt);
                    logIn.Debug(string.Format(" 找到 {0} 型新库位 {1}", enumWhLocVol.大整, locs.Count));
                    foreach (WmsLocation loc in locs)
                    {
                        decimal c2 = batch3Cnt > batchMax3 ? batchMax3 : batch3Cnt;
                        //  locsBatch2.Add(loc, c2);
                        locs2add.Add(loc, c2);
                        batch3Cnt -= batchMax3;
                        if (batch3Cnt < 0)
                        {
                            break;
                        }
                    }
                }
                catch (DeiNiuNoFreeLocationkException er) //大整货位不足
                {
                    logIn.Debug(string.Format(" 没有找到新库位。。。。"));
                }
                if (batch3Cnt > 0)
                {
                    batch2Cnt += batch3Cnt; ////大整货位不足,入小整
                    logIn.Debug(string.Format(" 大整 转 中整 数量{0}", batch3Cnt));
                    // batch2Cnt = 0;
                }
            }
            if (batch2Cnt > 0)
            {
                nearLocation.locationId = lastBatch2Location;
                decimal cnt = batch2Cnt / batchMax2;
                locCnt = (int)Math.Ceiling(cnt);//有余数则会进一位
                nearLocation.volType = (int)enumWhLocVol.中整;
                logIn.Debug(string.Format("需 {0} 型新库位 {1}", enumWhLocVol.中整, locCnt));
                List locs = null;
                try
                {
                    locs = nearLocation.getFreeLocation(nearLocation, (enumWhType)requestDetail.whType, locCnt);
                    logIn.Debug(string.Format(" 找到 {0} 型新库位 {1}", enumWhLocVol.中整, locs.Count));
                    foreach (WmsLocation loc in locs)
                    {
                        decimal c2 = batch2Cnt > batchMax2 ? batchMax2 : batch2Cnt;
                        //  locsBatch2.Add(loc, c2);
                        locs2add.Add(loc, c2);
                        batch2Cnt -= batchMax2;
                        if (batch2Cnt < 0)
                        {
                            break;
                        }
                    }
                }
                catch (DeiNiuNoFreeLocationkException er) //大整货位不足
                {
                    logIn.Debug(string.Format(" 没有找到新库位。。。。"));
                }
                if (batch2Cnt > 0)
                {
                    batch1Cnt += batch2Cnt; ////大整货位不足,入小整
                    logIn.Debug(string.Format(" 中整 转 小整 数量{0}", batch2Cnt));
                }
            }
            if (batch1Cnt > 0)
            {
                //  decimal cnt = ;
                locCnt = (int)Math.Ceiling(batch1Cnt / batchMax1);
                nearLocation.locationId = lastBatch1Location;
                nearLocation.volType = (int)enumWhLocVol.小整;
                List locs = null;
                logIn.Debug(string.Format("需 {0} 型新库位 {1}", enumWhLocVol.小整, locCnt));
                try
                {
                    locs = nearLocation.getFreeLocation(nearLocation, (enumWhType)requestDetail.whType, locCnt);
                    logIn.Debug(string.Format(" 找到 {0} 型新库位 {1}", enumWhLocVol.小整, locs.Count));
                    foreach (WmsLocation loc in locs)
                    {
                        decimal c1 = batch1Cnt > batchMax1 ? batchMax1 : batch1Cnt;
                        // locsBatch1.Add(loc.locationId, c1);
                        locs2add.Add(loc, c1);
                        batch1Cnt -= batchMax1;
                        if (batch1Cnt <= 0)
                        {
                            break;
                        }
                    }
                }
                catch (DeiNiuNoFreeLocationkException er) //小整货位不足
                {
                    logIn.Debug(string.Format(" 没有找到新库位。。。。"));
                }
                if (batch1Cnt > 0)
                {
                    if (batch2Cnt > 0) //大整货位不足,入零库
                    {
                        bulkCntFromBatch += batch1Cnt;
                        // bulkCnt += batch1Cnt;
                        batch1Cnt = 0;
                        logIn.Debug(string.Format("整库位不足,转零库数量 {0}", batch1Cnt));
                    }
                    else
                    { //入中整
                        logIn.Debug(string.Format("小整库位不足,转中整库数量 {0}", batch1Cnt));
                        batch2Cnt = batch1Cnt;
                        nearLocation.volType = (int)enumWhLocVol.中整;
                        nearLocation.locationId = lastBatch2Location;
                        locCnt = (int)Math.Ceiling(batch2Cnt / batchMax2);//有余数则会进一位
                        try
                        {
                            locs = nearLocation.getFreeLocation(nearLocation, (enumWhType)requestDetail.whType, locCnt);
                            foreach (WmsLocation loc in locs)
                            {
                                decimal c2 = batch2Cnt > batchMax2 ? batchMax2 : batch2Cnt;
                                //  locsBatch2.Add(loc, c2);
                                locs2add.Add(loc, c2);
                                batch2Cnt -= batchMax2;
                                if (batch2Cnt <= 0)
                                {
                                    break;
                                }
                            }
                            if (batch2Cnt > 0)
                            {
                                bulkCntFromBatch += batch2Cnt;
                                //bulkCnt += batch2Cnt; ////大小整货位不足,入零库
                                // batch2Cnt = 0;
                                logIn.Debug(string.Format("中整货位不足,入零库 {0}", batch2Cnt));
                            }
                        }
                        catch (DeiNiuNoFreeLocationkException er) //大小整货位不足
                        {
                            bulkCntFromBatch += batch1Cnt;
                            // bulkCnt += batch1Cnt;
                            batch1Cnt = 0;
                            logIn.Debug(string.Format("中整货位不足,入零库 {0}", batch1Cnt));
                        }
                    }
                }
                logIn.Debug(string.Format("大小整货位不足,计划共入零库 {0}, 是否允许 ?{1}", bulkCntFromBatch, WmsConstants.IN_STOCK_NO_BATCH_LOCATION_IN_BULK));
                batch3Cnt = 0;
                batch2Cnt = 0;
                batch1Cnt = 0;
                //如果不允许整货入零库则报异常
                if (!WmsConstants.IN_STOCK_NO_BATCH_LOCATION_IN_BULK && bulkCntFromBatch > 0)
                {
                    if (WmsConstants.NO_FREE_LOCATION_USE_TMP)
                    {
                        WmsLocation loc = new WmsLocation();
                        loc.locationId = WmsConstants.TMP_BATCH_LOCATION;
                        locs2add.Add(loc, bulkCntFromBatch);
                        bulkCntFromBatch = 0;
                        logIn.Debug(string.Format("中整货位不足,入虚拟库位 {0}", WmsConstants.TMP_BATCH_LOCATION));
                    }
                    else {
                        logIn.Error(string.Format("整货位不足,无法分配货位"));
                        isBatchException = true; throw new DeiNiuNoFreeLocationkException(string.Format("整货位不足,无法分配货位"));
                    }
                    // string msg = string.Format("{0}", location);
                }
                bulkCnt += bulkCntFromBatch;
            }
            logIn.Debug(string.Format("零库总计需入库数量 {0}", bulkCnt));
            if (bulkCnt > 0)
            {
                decimal cnt = bulkCnt / bulkMax;
                locCnt = (int)Math.Ceiling(cnt);
                nearLocation.volType = (int)enumWhLocVol.零库;
                nearLocation.locationId = lastBulkLocation;
                List locs = null;
                logIn.Debug(string.Format("需 {0} 型新库位 {1}", enumWhLocVol.零库, locCnt));
                try
                {
                    locs = nearLocation.getFreeLocation(nearLocation, (enumWhType)requestDetail.whType, locCnt);
                    logIn.Debug(string.Format(" 找到 {0} 型新库位 {1}", enumWhLocVol.零库, locs.Count));
                    foreach (WmsLocation loc in locs)
                    {
                        decimal c = bulkCnt > bulkMax*loc.scaleFactor ? bulkMax * loc.scaleFactor : bulkCnt;
                        //locsBulk .Add(loc.locationId, c );
                        locs2add.Add(loc, c);
                        bulkCnt -= bulkMax * loc.scaleFactor;
                        if (bulkCnt <= 0)
                        {
                            break;
                        }
                    }
                }
                catch (DeiNiuNoFreeLocationkException er) //零货位不足
                {
                    logIn.Debug(string.Format(" 没有找到新库位。。。。"));
                }
                //bulkCnt += 500;//for debug
                if (bulkCnt > 0) //get locations from other sharing locations
                {
                    logIn.Debug(string.Format(" 零库需入库数量 {0}  ,开始找共享库位", bulkCnt));
                    // string msg = string.Format("{0}", location);
                    decimal goodsMaxcnt = goods.getMaxCount((int)enumWhLocVol.零库);
                    locCnt = (int)Math.Ceiling(bulkCnt / goodsMaxcnt) * 50;
                    dt = stock.queryOtherSharingLocations(goods, (int)enumWhLocVol.零库, locCnt,
                        (enumWhType)requestDetail.whType);
                    lastLoc = "";
                    logIn.Debug(string.Format("找到共享库位 {0}个   ", dt.Rows.Count));
                    foreach (DataRow dr in dt.Rows)
                    {
                        stock = new WmsStock(dr);
                        if (lastLoc == "")
                        {
                            lastLoc = stock.locationId;
                        }
                        else
                            if (lastLoc.Equals(stock.locationId))
                        {
                            continue;
                        }
                        lastLoc = stock.locationId;
                        lastBulkLocation = stock.locationId;
                        decimal freeCntCapicity = Math.Ceiling((1 - Convert.ToDecimal(dr["usedPercent"].ToString())) * goodsMaxcnt* stock.location.scaleFactor);
                        logIn.Debug(string.Format("共享库位 {0} ,可用空间 {1}  ", lastBulkLocation, freeCntCapicity));
                        if (freeCntCapicity <= 0)
                        {
                            continue;
                        }
                        if (bulkCnt > freeCntCapicity)
                        {
                            //locsUpdate.Add(new WmsStock( stock.locationId,stock.skuId), freeCntCapicity);
                            locs2add.Add(new WmsLocation(stock.locationId), freeCntCapicity);
                            bulkCnt -= freeCntCapicity;
                        }
                        else
                        {
                            // locsUpdate.Add(new WmsStock( stock.locationId,stock.skuId), bulkCnt);
                            locs2add.Add(new WmsLocation(stock.locationId), bulkCnt);
                            bulkCnt = 0;
                            break;
                        }
                    }
                    if (bulkCnt > 0)
                    {
                        logIn.Debug(string.Format("零库需入库数量 {0}  ", bulkCnt));
                        if (WmsConstants.NO_FREE_LOCATION_USE_TMP)
                        {
                            WmsLocation loc = new WmsLocation();
                            loc.locationId = WmsConstants.TMP_BULK_LOCATION;
                            locs2add.Add(loc, bulkCnt);
                            bulkCnt = 0;
                        }
                        else
                        {
                            logIn.Debug(string.Format("零库需入库数量 {0},无可用库位  ", bulkCnt));
                            throw new DeiNiuNoFreeLocationkException(string.Format("零库需入库数量 {0},无可用库位  ", bulkCnt));
                        }
                    }
                }
            }
        }
            foreach (var item in locs2add)
            {
                if (item.Value <= 0)
                {
                    continue;
                }
                stock = new WmsStock();
                stock.locationId = item.Key.locationId;
                if (WmsConstants.IN_STOCK_PDA_SCAN)
                {
                    stock.countIn += item.Value;
                }
                else
                {
                    stock.count = item.Value;
                }
                stock.goodsId = requestDetail.goodsId;
                stock.batch = requestDetail.batch;
                stock.productDate = requestDetail.productDate;
                stock.validDate = requestDetail.validDate;
                stock.validationTerm = 1;
                stock.operater = this.operId;
                stock.state = (int)enumStockLocationStatus.正常;
                stock.skuCode = skuCode;
                stock.skuId = skuId;
                stock.maintainDate = stock.getDateTime();
                if (String.IsNullOrEmpty(stock.batch))
                {
                    stock.batch = requestDetail.productDate;
                }
                stock.Add();
                logStock(requestDetail, stock, item.Value, enumInStoreType.普通入库);
                logIn.Debug(string.Format(" add locationid {0}, count{1} ", stock.locationId, item.Value));
            }
            // to update location count in stock
            //    Dictionary locsUpdateStock = new Dictionary();
            // locsBatch1.Union(locsBatch2).Union(locsBulk);  //合并
            //locsUpdateStock.Concat(locsBatch1).Concat(locsBatch2).Concat(locsBulk);  //合并
            //  mergeDictionary(locsBulk, mergeDictionary(locsBatch2, mergeDictionary(locsBatch1, locsUpdateStock)));
            foreach (var item in locsUpdate)
            {
                if (item.Value <= 0)
                {
                    continue;
                }
                stock = item.Key;
                if (WmsConstants.IN_STOCK_PDA_SCAN)
                {
                    stock.countIn += item.Value;
                }
                else
                {
                    stock.count += item.Value;
                }
                stock.operater = this.operId;
                stock.Update();
                logStock(requestDetail, stock, item.Value, enumInStoreType.普通入库);
                logIn.Debug(string.Format(" update stock locationid {0}, count{1} ", stock.locationId, item.Value));
            }
            return batch2Cnt + batch1Cnt + bulkCnt <= 0;
        }
        /// 
        /// 关收货单
        /// 关单后
        /// 1. 此收货单不可以再收货
        /// 2. 通知ERP 收货情况
        /// 3. 所有未开始的上架任务开始动
        /// 
        /// 
        /// 启
        internal enumRepResult preInDone(string preInNo,bool isZhitongAuto = false)
        { 
            logIn.Debug(string.Format("start to 完验 {0}, isZhitongAuto {1}",preInNo,isZhitongAuto)); 
            
            WmsFlow wmsFlow = new WmsFlow(preInNo);
            if(wmsFlow.state == (int)enumFlowTaskStatus.已完成)
            {
                logIn.Debug("start to 完验 " + (enumFlowTaskStatus)wmsFlow.state);
               // return enumRepResult.成功;
            }
            int cnt = 0; 
            
            List lst = preInObj.getPuchObjescts(preInNo);
            foreach (Erp_purch obj in lst)
            {
                if (obj.wms_state >= (int)enumInStockOrderStatus.完验)
                {
                    return enumRepResult.成功;
                }
               // obj.Update();
            }
            using (TransactionScope scope = new TransactionScope())
            {
                
              
                wmsFlow.startAllTask(preInNo);
                if (isZhitongAuto && WmsConstants.IN_STOCK_ZHITONG_PREDONE_AUTO_VALIDATION)
                {
                    logIn.Debug("start to auto valid zhitong items ");
                    autoValidInZhitong2(preInNo);
                    wmsFlow.finishedTasksPlus(operId,0,true,true);
                    logIn.Debug("end auto valid zhitong items ");
                }
                 
                 cnt = preInObj.preDone(preInNo, operId);
                logIn.Debug("  完验 更新 记录 " + cnt);
                foreach (Erp_purch obj in lst)
                {
                    obj.wms_state = (int)enumInStockOrderStatus.完验;
                    obj.Update();
                    WmsInRequest win = new WmsInRequest(obj.pur_order);
                    win.state = (int)enumInStockOrderStatus.完验;
                    win.Update();
                }
                scope.Complete();
            }
         
            logIn.Debug("  完验 to notice erp purch order cnt  " + lst.Count);
            logIn.Debug(string.Format(" isZhitongAuto {0}, ERP_NOTICE_STOCK_IN_WHEN_FINISH_UP {1}",
                isZhitongAuto, WmsConstants.ERP_NOTICE_STOCK_IN_WHEN_FINISH_UP));
            WmsInUpPort wmsInUpPort = new WmsInUpPort();
            foreach (Erp_purch obj in lst)
            {
                if(!isZhitongAuto && WmsConstants.ERP_NOTICE_STOCK_IN_WHEN_FINISH_UP) //非直通、先上架后再回传erp
                {
                    //inupport state should be >1, or continiue
                    bool isFinishUp = wmsInUpPort.isDoneByOrderNo(obj.pur_order);
                    logIn.Debug(string.Format(" pur order {0} is finished up shelf: {1} ", obj.pur_order,isFinishUp));
                    if (!isFinishUp)
                    {
                        logIn.Debug(string.Format(" pur order {0} is not finished up shelf, not to notice erp",obj.pur_order ));
                        continue;
                    }
                      
                }
                noticeErpValiIn(obj);
                Thread.Sleep(50);
            }
            return cnt>0? enumRepResult.成功:enumRepResult.失败;
        }
        internal enumRepResult stackDone(string preInNo, string flowNo)
        {
            lWmsFlow lf = new lWmsFlow(operId);
            enumFlowTaskResult efr = enumFlowTaskResult.失败;
            using (TransactionScope scope = new TransactionScope())
            {
                efr = lf.startTask(preInNo, flowNo);
                WmsFlow flow = new WmsFlow(preInNo);
                flow.finishedCnt = flow.taskCnt;
                flow.state = (int)enumFlowTaskStatus.已完成;
                // flow.owner = operId;
                flow.Update();
                scope.Complete();
            }
            if (efr == enumFlowTaskResult.成功)
            {
                return enumRepResult.成功;
            }
            return enumRepResult.失败;
        }
        internal DataTable getZhiTongOrderByCust(string preNo, string orderBy, string barcode = "")
        {
            return getWmsInRequest.getZhiTongOrderByCust(preNo, orderBy, barcode);
        }
        internal enumRepResult newBarcode(string goodsId, string barcode, decimal packingQty, decimal chang, decimal kuan, decimal gao, decimal weight)
        {
            ErpGoods goods = new ErpGoods(goodsId);
            if (goods.ID > 0)
            {
                if (String.IsNullOrEmpty(goods.barCode))
                {
                    goods.barCode = barcode;
                    goods.Update();
                }
                DataTable dt = new Erp_packing().queryByGoodsId(goodsId);
                DataView dv = dt.DefaultView;
                dv.RowFilter = "barcode='" + barcode + "'";
                if (dv.Count == 0)
                {
                    Erp_packing ep = new Erp_packing();
                    ep.goodsId = goodsId;
                    ep.packingQty = packingQty;
                    ep.chang = chang;
                    ep.kuan = kuan;
                    ep.gao = gao;
                    ep.weight = weight;
                    ep.Add();
                }
                return enumRepResult.成功;
            }
            return enumRepResult.失败;
        }
        internal enumRepResult zhiTongSeedOut(int outDetailId, int inDetailId, decimal seedCnt, string flowNo,bool isOnce=false)
        {
            logIn.Debug(string.Format("outPickDetailId: {0}, inDetailId: {1}, seedCnt :{2}, flowNo: {3}", outDetailId, inDetailId, seedCnt, flowNo));
            WmsInRequestDetail wid = new WmsInRequestDetail(inDetailId);
            WmsOutPickDetail wod = new WmsOutPickDetail(outDetailId);
            wod.seeded += seedCnt;
            wid.receiveCount += seedCnt;
            using (TransactionScope scope = new TransactionScope())
            {
               // wod.state = (int)enumOutStockDetailStatus.正在分拣;
                if (isOnce)
                {
                    logIn.Debug(" 商品每个店只分一次 isOnce " + isOnce);
                    wod.state = (int)enumOutStockDetailStatus.播种完成;
                }
                else
               if(  wod.goods.isWeightOut() ) //称重的分货在分货重量误差允许范围内,结单
                {
                    decimal overRate = Math.Abs( wod.count - wod.seeded ) * 100 / wod.count;
                    if ( overRate < WmsConstants.OVER_WEIGHT_PERCENT_ALLOW)
                    {
                        wod.state = (int)enumOutStockDetailStatus.完成分拣;
                    }
                }
                else
                if (wod.seeded >= wod.count)
                {
                    wod.state = (int)enumOutStockDetailStatus.完成分拣;
                }
                wod.Update();
                if (wod.state == (int)enumOutStockDetailStatus.完成分拣 && wod.isAllPicked(wod.pickOrderNo))
                {
                    WmsOutPickRequest wopk = new WmsOutPickRequest(wod.pickOrderNo);
                    wopk.state = (int)enumOutStockRequestStatus.分拣完成;
                    wopk.Update();
                }
                
                wid.Update();
                WmsStockRecord wsr = new WmsStockRecord();
                wsr.skuId = wid.skuId;
                wsr.productDate = wid.productDate;
                wsr.batch = wid.batch;
                wsr.orderNo = wod.pickOrderNo;
                wsr.orderDetailId = wod.ID;
                wsr.skuId = wid.skuId;
                wsr.goodsId = wid.goodsId;
                wsr.count = seedCnt;
                wsr.locationId = wid.partion + "";
                wsr.rectype = (int)enumStockRecordType.直通越仓;
                wsr.Add();
                WmsOutPickPort wop = new WmsOutPickPort();
                wop.flowNo = flowNo;
                wop.recordId = wsr.ID;
                wop.pickBy = operId;
                wop.takeBy = operId;
                wop.pickTime = wop.getDateTime();
                wop.partion = wid.partion;
                wop.pickCount = seedCnt;
                wop.pickOrderNo = wid.preInOrder;// new WmsOutRequest( wid.poNo).pickOrderNo;
                wop.state = (int)enumPickState.已分播;
                wop.recType = (int)enumStockRecordType.直通越仓;
                //TODO: get trans info
                //wop.tranArea=Gettranear;
                //wop.tranLocationId =
                wop.Add();
                WmsPlate plate = new WmsPlate(flowNo);
                if (!WmsConstants.AUTO_LOAD_TRUCK && plate.type != (int)enumPlateLevel.客户集货)
                { 
                    WmsFlow jiFlow = new WmsFlow(wod.pickOrderNo, flowNo, enumFlowTaskStatus.未开始, EnumFlowTaskType.客户集货);
                    if (jiFlow.ID == 0)
                    {
                        jiFlow.operater = operId;
                        jiFlow.orderNo = wod.pickOrderNo;
                        jiFlow.flowNo = flowNo;
                        jiFlow.type = (int)EnumFlowTaskType.客户集货;
                        jiFlow.typeName = EnumFlowTaskType.客户集货.ToString();
                        jiFlow.task = wod.pickOrderNo + flowNo;
                        jiFlow.taskCnt = 1;
                        jiFlow.Add();
                         
                    } 
                }
                scope.Complete();
            }
            return enumRepResult.成功;
        }
        /*
         private Dictionary addLocsUpdate(Dictionary locsUpdate, string locationId, decimal count)
         {
             if (locsUpdate.Keys.Contains(locationId))
             {
                 locsUpdate[locationId] += count;
             }
             else
             {
                 locsUpdate[locationId] = count;
             }
             return locsUpdate;
         }
         private Dictionary mergeDictionary(Dictionary dic1, Dictionary dicto)
         {
             foreach (WmsStock key in dic1.Keys)
             {
                 dicto[key] = dic1[key];
             }
             return dicto;
         }
        */
        private void logStock(WmsInRequestDetail requestDetail, WmsStock stock, decimal count,
                                        enumInStoreType inStoreType, WmsStockPre stockPre = null)
        {
            logIn.Debug("log stock wid:" + requestDetail.ToString());
            logIn.Debug(string.Format(" inStoreType {0}",inStoreType.ToString()));
            WmsStockRecord r = new WmsStockRecord();
            r.batch = requestDetail.batch.Trim();
            if (WmsConstants.IN_STOCK_PDA_SCAN)
            {
                r.countIn = count;
            }
            else
            {
                r.count = count;
            }
            int recType = (int)enumStockRecordType.普通入库;
            switch ((enumWhType)requestDetail.whType)
            {
                case enumWhType.不合格库:
                    recType =  (int)enumStockRecordType.不良品入库;
                    break;
                case enumWhType.越仓收货区:
                      recType = (int)enumStockRecordType.直通越仓;
                    break;
                case enumWhType.退货库:
                    recType = (int)enumStockRecordType.退货入库;
                    break;
                case enumWhType.合格库:
                    recType = (int)enumStockRecordType.普通入库;
                    break;
                case enumWhType.虚拟库:
                    recType = (int)enumStockRecordType.虚拟入库;
                    break;
            }
           
           if (inStoreType == enumInStoreType.直接上架)
            {
                recType = (int)enumStockRecordType.入库直接上架;
                r.countIn = 0;
                r.count1 = count;
                r.count = count;
            }
            r.goodsId = requestDetail.goodsId.Trim();
            if (stock != null)
            {
                WmsLocation loc = new WmsLocation(stock.locationId.Trim());
                r.partion = loc.partion;
               /*
                if (loc.partion ==0 || loc.part > 0)
                {
                    Node nd = new Node(loc.part);
                    r.partion = nd.flag;
                }*/
                r.locationId = stock.locationId.Trim();
                r.productDate = stock.productDate;
                r.validDate = stock.validDate;
            }
            if (stockPre != null)
            {
                r.locationId = stockPre.partion + "";
                r.productDate = stockPre.productDate;
                r.validDate = stockPre.validDate;
            }
            r.orderNo = requestDetail.orderNo.Trim();
            r.regeditCode = requestDetail.regeditCode.Trim();
            r.rectype = recType;//in
            r.operater = this.operId;
            r.skuCode = requestDetail.skuCode;
            r.skuId = requestDetail.skuId;
            r.orderDetailId = requestDetail.ID;
            r.Add();
         
            if (WmsConstants.IN_STOCK_PDA_SCAN)
            {
                EnumFlowTaskType taskType = Util.getTaskType(r.rectype);
                WmsFlow wmsflow = new WmsFlow(requestDetail.preInOrder, requestDetail.flowNo, enumFlowTaskStatus.未开始, taskType);
                if (wmsflow.ID == 0 || wmsflow.taskPartion != r.partion )
                {
                    wmsflow.operater = operId;
                    wmsflow.orderNo = requestDetail.preInOrder;
                    wmsflow.flowNo = requestDetail.flowNo;
                    wmsflow.type = (int)taskType; 
                    wmsflow.typeName = taskType.ToString();
                    wmsflow.task = Util.getOrderNo(enumCreateOrderType.pickJobNo, _obj.getNextSeq(enumCreateOrderType.pickJobNo)); ;
                    wmsflow.taskPartion = r.partion;
                    wmsflow.toPartion = r.partion;
                    // wmsflow.toLocationId = r.locationId; 
                    wmsflow.taskCnt=1;
                    wmsflow.Add();                
                }
                else
                {
                    wmsflow.taskCnt++;
                    wmsflow.Update();
                }
                requestDetail.taskNo = wmsflow.task;
                requestDetail.Update();
                if (inStoreType == enumInStoreType.直接上架 || inStoreType== enumInStoreType.虚拟入库冲抵)
                {
                    /* wmsflow.finishedCnt = wmsflow.taskCnt;
                     wmsflow.owner = operId;
                     wmsflow.state = (int)enumFlowTaskStatus.已完成;
                     wmsflow.Update();
                     wmsflow.finishedPcs = 1;
                     */
                    decimal finishedPcs = requestDetail.outDetailId > 0  //直通
                        ?( wmsflow.flowNo.StartsWith("zt") //强制完验
                            ? wmsflow.taskCnt :  count ) 
                        : 1;
                    wmsflow.finishedTasksPlus(operId, finishedPcs); // 直通强制
                    return;
                }
                WmsInUpPort inPort = new WmsInUpPort();    
                inPort.count = count;
                inPort.orderNo = requestDetail.orderNo;
                inPort.locationId = r.locationId;//stock.locationId;
                inPort.recordId = r.ID;
                inPort.detailId = requestDetail.ID;
                inPort.productDate = r.productDate;
                inPort.validDate = r.validDate;
                inPort.goodsId = r.goodsId;
                inPort.batch = r.batch;
                inPort.recType = r.rectype;
                inPort.operater = this.operId;
                inPort.state = (int)enumInStockDetailStatus.已分配货位;
                if (inStoreType == enumInStoreType.直接上架)
                {
                    inPort.state = (int)enumInStockDetailStatus.上架完成;
                }
                 
                inPort.skuCode = requestDetail.skuCode;
                inPort.skuId = requestDetail.skuId;
                inPort.flowNo = requestDetail.flowNo;
                inPort.inPreOrder = requestDetail.preInOrder;
                inPort.partion = r.partion;
                inPort.volType = stock==null? (int)enumWhLocVol.取总分播区: stock.location.volType;
                inPort.jobNo = wmsflow.task;// Util.getOrderNo(enumCreateOrderType.pickJobNo, _obj.getNextSeq(enumCreateOrderType.pickJobNo));//TODO: use flow's job no
                
                if (recType == (int)enumStockRecordType.直通越仓)
                {
                    inPort.upCount = count;
                }
                inPort.Add();
                //新增临时容器库存
                
                WmsPlateStock_tmp plateStock = new WmsPlateStock_tmp();
                plateStock.plateId = inPort.flowNo;
                plateStock.goodsId = inPort.goodsId;
                plateStock.productDate = inPort.productDate;
                plateStock.validDate = inPort.validDate;
                plateStock.batch = String.IsNullOrEmpty(inPort.batch)?inPort.productDate:inPort.batch;
                plateStock.batch = String.IsNullOrEmpty(plateStock.batch) ? plateStock.getDateTime() : plateStock.batch;
               plateStock.count = inPort.count;
                //plateStock.state = ;
                plateStock.skuCode = inPort.skuCode;
                plateStock.skuId = inPort.skuId;
                plateStock.orderNo = inPort.orderNo;
                plateStock.locationid = inPort.locationId;//目标location
                plateStock.jobNo = inPort.jobNo;
                plateStock.recType = inPort.recType;
                plateStock.recordId = inPort.recordId;
                plateStock.inPortId = inPort.ID;
                plateStock.operater =operId;
                if(inStoreType == enumInStoreType.直通越仓)
                {
                    plateStock.state = (int)enumPlateStatus.取总待分播;
                }
               
                if (inStoreType != enumInStoreType.直接上架)
                {
                    plateStock.Add();
                }
                /*
                        //任务
                        WmsFlow wmsflow = new WmsFlow();
                        wmsflow.operater = operId;
                        wmsflow.orderNo = requestDetail.preInOrder;
                        wmsflow.flowNo = requestDetail.flowNo;
                        wmsflow.type = (int)Util.getTaskType(inPort.recType); ;
                        wmsflow.typeName = Util.getTaskType(inPort.recType).ToString();
                        wmsflow.task = inPort.jobNo;
                        wmsflow.taskPartion = inPort.partion;
                        wmsflow.toLocationId = r.locationId;
                        wmsflow.taskCnt = 1;
                        wmsflow.Add();
                        */
                /*//add up shelf task
                string jobNo = Util.getOrderNo(enumCreateOrderType.preInOrder, _obj.getNextSeq(enumCreateOrderType.preInOrder));
                WmsFlow wmsflow = new WmsFlow();
                wmsflow.operater = operId;
                wmsflow.orderNo = r.orderNo;
                wmsflow.type = (int)Util.getTaskType(inPort.recType);
                 wmsflow.task = jobNo;
                // wmsflow.fromPartion = inPort.partion;
                 wmsflow.toPartion = inPort.partion;
                 wmsflow.taskPartion = inPort.partion;
                wmsflow.Add();
                */
            }
        }
        public bool deleteInRequest(string orderNo)
        {
            WmsInRequest inr = new WmsInRequest(orderNo);
            bool r = false;
            if ((enumInStockOrderStatus)inr.state == enumInStockOrderStatus.已入库)
            {
                return false;
            }
            using (TransactionScope scope = new TransactionScope())
            {
                r = inr.deleteRequest(orderNo);
                scope.Complete();
            }
            return r;
        }
        /// 
        /// PDA入库上架单列表
        /// 
        /// 预打印的上架流水号 
        /// 
        public DataTable getPortStockInDetailsByFlowNo(string flowNo)
        {
            //return getWmsInRequest.getStockInDetail(id);
            return getWmsInRequest.getInPortDetails(flowNo);
        }
        /// 
        /// PDA入库上架单明细
        /// 
        /// 上架 port Id 
        /// 
        public DataTable getPortStockInDetailByPortId(int portId)
        {
            //return getWmsInRequest.getStockInDetail(id);
            return getWmsInRequest.getInPortDetail(portId);
        }
        internal enumRepResult finishUpShelfItem(string flowNo, int portId, decimal count, string locationId, string reason)
        {
            WmsInUpPort inPort = new WmsInUpPort(portId);
            //  logIn.Debug(string.Format("开始上架 portId :{0}, locationId {1}, count: {2}, status: {3}}",  portId, locationId, count, inPort.state));
            logIn.Debug(Util.getJson(inPort));
            if (count <= 0)
            {
                return enumRepResult.上架数量错误;
            }
            if (inPort.state == (int)enumInStockDetailStatus.上架完成)
            {
                logIn.Debug(" 任务已上架,中断上架。");
                return enumRepResult.状态已完成上架;
            }
            inPort.upCount += count;
            if (inPort.upCount > inPort.count)
            {
                return enumRepResult.上架数量大于应上数量;
            }
            string description = string.Format("\n 业务类型:{0},目标货位{1},实际货位{2} 上架数量{3}, 备注:{4}",
            ((enumStockRecordType)inPort.recType).ToString(), inPort.locationId, locationId, count, reason);
            logIn.Debug(description);
            WmsStockRecord sr1 = new WmsStockRecord();
            sr1.count = count;
            sr1.count1 = inPort.upCount;
            sr1.goodsId = inPort.goodsId;
            sr1.batch = inPort.batch;
            sr1.skuId = inPort.skuId;
            sr1.skuCode = inPort.skuCode;
            sr1.description = description;
            sr1.orderNo = inPort.orderNo;
            sr1.operater = operId;
            sr1.rectype = inPort.recType;
            sr1.productDate = inPort.productDate;
            sr1.validDate = inPort.validDate;
            sr1.locationId = locationId;
            sr1.skuCode = inPort.skuCode;
            sr1.skuId = inPort.skuId;
            sr1.orderDetailId = inPort.detailId;
            WmsStock stk = new WmsStock(inPort.locationId, inPort.skuId, inPort.goodsId); //
            lWmsStock lsk = new lWmsStock(operId);
            enumRepResult rp = lsk.validLocation(locationId, inPort.goodsId, inPort.skuId, inPort.batch, inPort.count);
           
            logIn.Debug(inPort);
            logIn.Debug("getStk: "+ stk);
            if (stk.ID == 0)
            {
                logIn.Debug(" why no stk id? target location valid result: " + rp);
                if (rp != enumRepResult.成功)
                {
                    logIn.Error("no stk id, target location valid result: " + rp);
                    return rp;
                }
                stk.skuCode = inPort.skuCode;
                stk.goodsId = inPort.goodsId;
                stk.skuId = inPort.skuId;
                stk.locationId = locationId;
                stk.batch = inPort.batch;
                stk.productDate = inPort.productDate;
                stk.validDate = inPort.validDate;
                stk.maintainDate = stk.getDateTime();
            }
            //WmsStock stk2; ;
            stk.operater = operId;
            stk.countIn -= count;
            stk.countIn = stk.countIn > 0 ? stk.countIn : 0;
            if (locationId == inPort.locationId)
            {
                stk.count += count;
            }
            else
            {
                inPort.description += string.Format(";{0}:{1}:{2}:{3}", locationId, count, operId, DateTime.Now);
            }
            enumRepResult result = enumRepResult.成功;
            WmsStockRep repStk = new WmsStockRep();
            logIn.Debug(string.Format("finish up shelf, flowNo :{0}, portId :{1},locationid: {2}, count {3}, recType :{4}", flowNo, portId, locationId, count, (enumStockRecordType)inPort.recType));
            if (inPort.recType == (int)enumStockRecordType.补零入库)
            {
                repStk = new WmsStockRep(inPort.goodsId, inPort.skuId);
                if (repStk.ID == 0)
                {
                    repStk = new WmsStockRep(inPort.goodsId, 0); //出库订单不指定skuId,补货入库也不指定
                }
                logIn.Debug(string.Format("1 get rep stock, {0}", repStk));
            }
            WmsFlow flow = new WmsFlow(inPort.jobNo);
            using (TransactionScope scope = new TransactionScope())
            {
                if (0 < inPort.upCount && inPort.upCount < inPort.count)
                {
                    inPort.state = (int)enumInStockDetailStatus.部分上架;
                }
                else if (inPort.upCount == inPort.count)
                {
                    inPort.state = (int)enumInStockDetailStatus.上架完成;
                    // flow.taskCnt++;
                    flow.finishedTasksPlus(operId,inPort.upCount/new WmsGoods(inPort.goodsId).bigCount); 
                   
                }
                inPort.operater=operId; 
                inPort.Update();
                sr1.Add();
                if (stk.ID == 0)
                {
                    stk.Add();
                }
                if (locationId != inPort.locationId) //手工指定货位
                {
                    WmsLocation loc = new WmsLocation(locationId);
                    if (loc.ID == 0)
                    {
                        return enumRepResult.货位不存在;
                    }
                    WmsInUpPort newPort = new WmsInUpPort(inPort.getDetail(inPort.ID).Rows[0]);
                    newPort.state = (int)enumInStockDetailStatus.上架完成;
                    newPort.count = count;
                    newPort.upCount = count;
                    newPort.description = description;
                    newPort.locationId = locationId;
                    newPort.Add();
                    /*
                    WmsStock newStk = new WmsStock(  locationId,inPort.skuId);
                    if (newStk.ID == 0) //new one
                    {
                        newStk.skuCode = inPort.skuCode;
                        newStk.goodsId = inPort.goodsId;
                        newStk.skuId = inPort.skuId;
                        newStk.locationId = locationId;
                        newStk.batch = inPort.batch;
                        newStk.productDate = inPort.productDate;
                        newStk.validDate = inPort.validDate;
                        newStk.maintainDate = newStk.getDateTime();
                        newStk.Add();
                    }
                    */
                    result = new lWmsStock(this.operId).upDownGoodsCountWithLocation(locationId, inPort.goodsId, inPort.skuId, inPort.batch, count, "",
                        enumStockRecordType.普通入库, inPort.recordId);
                    if (result != enumRepResult.成功)
                    {
                        scope.Dispose();
                        return result;
                    }
                }
                if (stk.ID > 0) // always should be existed already.
                    stk.updateCountOut();
#if DEBUG
                stk = new WmsStock(inPort.locationId, inPort.skuId, inPort.goodsId); // to remove
                logIn.Debug("updated stk: " + stk);
#endif
                //--处理临时库位(容器)的数据,释放容器。
                //--处理移库下架后的临时库位(容器)的数据
                //--处理入库验收后的临时库位(容器)的数据
                if (inPort.recType == (int)enumStockRecordType.补零入库) {
                     
                    WmsOutPickPort wop = new WmsOutPickPort();
                    wop.getPickPortByRecordId(inPort.recordId);
                    WmsOutPickDetail wopd = new WmsOutPickDetail(wop.pickDetailId);
                    if (wopd.isAllPicked(wopd.pickOrderNo))
                    {
                        logIn.Debug(" 补零单 ,全部完成 " + inPort.orderNo);
                        WmsOutPickRequest wpr = new WmsOutPickRequest(inPort.orderNo);
                        wpr.state = (int)enumOutStockRequestStatus.订单完成;
                        wpr.Update();
                    }  
                       
                    new lWmsPlate(operId).releasePlateStock(flowNo, count, 0, wop.ID);
                }
                else
                    new lWmsPlate(operId).releasePlateStock(flowNo, count, portId);
                //-- 处理补货库
                //  logIn.Debug(string.Format("2 get rep stock, {0}",repStk));
                if (repStk.ID > 0)
                {
                    logIn.Debug(string.Format(" to update rep stock, {0}", repStk));
                    repStk.repCont += count;
                    if (repStk.lackCount < 0)
                    {
                        if (repStk.lackCount + count > 0)
                        {
                            repStk.lackCount = 0;
                        }
                        else
                        {
                            repStk.lackCount = repStk.lackCount + count;
                        }
                    }
                    logIn.Debug(string.Format(" update rep stock, {0}", repStk));
                    repStk.Update();
                }
                logIn.Debug("to check all jobs in validin detail  " + inPort.detailId);
                if (inPort.isDoneByDetailId(inPort.detailId) )
                { 
                    logIn.Debug(" isDoneByDetailId ? " + true);
                 
                   
                        getWmsInRequest.finishUpShelf(inPort.orderNo, inPort.detailId, operId); //更新订单及明细状态
                        //更新ERP 上架数据  
                       updateErpDetail(inPort.detailId);
                    
                }
                // if (inPort.isDoneByOrderNo(inPort.orderNo))
                {
                }
                 
                scope.Complete();
            }
            return enumRepResult.成功;
        }
        /// 
        /// 待收货列表
        /// 
        /// 
        /// 
        /// 
        /// 
        public DataSet queryReceives(string querystr, int rownumStart, int rownumEnd)
        {
            return erpPurchObj.queryReceiveNos(querystr, rownumStart, rownumEnd);
        }
        /// 
        /// 收货、原始采购订单明细
        /// 
        /// 
        /// 
        public DataTable getRequestInDetail(string orderNo, int status = -1)
        {
            return erpPurchObj.queryPurchDetail(orderNo, status); ;
        }
        public DataTable getRequestDetailByVender(string venderName, int status = -1)
        {
            return erpPurchObj.getRequestDetailByVender(venderName, status); ;
        }
        /// 
        /// 收货、原始采购订单明细
        /// 
        /// 
        /// 
        public DataTable get4ValidDetail(string orderNo)
        {
            return erpPurchObj.get4ValidDetail(orderNo); ;
        }
        /// 
        /// 记录收货明细
        /// 
        /// 
        /// 到货数量
        /// 收货数量、拒收数量
        /// 0:收货,1:拒收
        /// 
        /// 
        internal bool receiveDetail(string preInNo, int id, decimal arriveNumber, decimal count, int inType, string inRemark,
            int shipId, bool isCache, int cachePartion, decimal temperature = 0)
        {
            Erp_purch_d epd = new Erp_purch_d(id);
            if (epd.count == 0)
            {
                return false;
            }
            decimal rcNumber = inType == 0 ? count : 0;
            decimal rjNumber = inType == 1 ? count : 0;
            epd.arriveCount += arriveNumber;
            epd.receiveCount += rcNumber;
            epd.rejectCount += rjNumber;
            epd.storeType = isCache ? 1 : 0;
            epd.zhitongPartion = cachePartion;
            enumReceiveStockDetailStatus nextState = enumReceiveStockDetailStatus.待验收;
            WmsGoods wg = new WmsGoods(epd.goods_id);
            if (wg.ID == 0)
            {
                log.Error(epd.goods_id + " is not exists in wms");
                throw new Exception("未知商品" );
            }
            if (!wg.isQc)
            {
                nextState = enumReceiveStockDetailStatus.已验收;
            }
            if (!WmsConstants.IN_STOCK_OVER_RECEIVE)
            {
                epd.receiveCount = epd.receiveCount > epd.count ? epd.count : epd.receiveCount;
            }
            if (epd.receiveCount > 0)
            {
                if (epd.receiveCount + epd.rejectCount >= epd.count)  //应收数量计算,包含拒收数量
                {
                    epd.wms_state = (int)nextState;
                }
            }
            else
            {
                if (epd.rejectCount >= epd.count)
                {
                    epd.wms_state = (int)enumReceiveStockDetailStatus.拒收;
                }
            }
            epd.operater = this.operId;
            epd.receiveRemark = inRemark;
            //add receive log
            Erp_purch_receive_log erl = new Erp_purch_receive_log();
            erl.preInOrder = preInNo;
            erl.arriveCount = arriveNumber;
            erl.receiveCount = rcNumber;
            erl.rejectCount = rjNumber;
            erl.receiveRemark = inRemark;
            erl.shipId = shipId;
            erl.operater = this.operId;
            erl.pur_order = epd.pur_order;
            erl.purch_d_id = epd.ID;
            erl.temperature = temperature;
            DataTable dt = getRequestInDetail(epd.pur_order);
            //  using (TransactionScope scope = new TransactionScope())
            {
                erl.Add();
                epd.Update();
                bool isReject = true;
                bool isAllProceed = true;
                foreach (DataRow dr in dt.Rows)
                {
                    if ( Convert.ToInt32(dr["wms_state"].ToString()) == (int)enumReceiveStockDetailStatus.待收货)
                    {
                        isAllProceed = false;
                        isReject = false;
                        break;
                    }
                    isReject = isReject
                        && ( Convert.ToInt32(dr["wms_state"].ToString()) == (int)enumReceiveStockDetailStatus.拒收);
                }
                // process order
                Erp_purch ep = new Erp_purch(epd.pur_order);
                ep.operater = this.operId;
                if (isAllProceed)
                {
                    ep.wms_state = isReject ? (int)enumInStockOrderStatus.已拒收 : (int)nextState;
                    ep.Update();
                }
                else
                {
                    if (rcNumber > 0)
                    {
                        //ep.wms_state = isReject ? (int)enumInStockOrderStatus.已拒收 : (int)enumInStockOrderStatus.待验收;
                        ep.canValid = !isReject;  //部分验收
                        ep.Update();
                    }
                }
                //to create/update inRequest,indetail for no qc goods.
                if (!wg.isQc)
                {
                    if (string.IsNullOrEmpty(epd.batch) || string.IsNullOrEmpty(epd.productDate) || string.IsNullOrEmpty(epd.validDate))
                    {
                        // return false; // 就是如果有嵌套事务 如果里层的事务在执行的过程没有Complete()
                    }
                    createInrequest4NoQc((enumInOrderType)ep.orderType, epd, isCache, cachePartion, wg);
                }
                //   scope.Complete();
            }
            return true;
        }
        void createInrequest4NoQc(enumInOrderType orderType, Erp_purch_d epd, bool isCache, int cachePartion, WmsGoods wg)
        {
            StructsValideIn svi = new StructsValideIn();
            svi.goods_id = epd.goods_id;
            svi.flowNo = epd.ID + "";
            svi.seeds_count = 0;
            svi.valid_count = epd.count;
            svi.validby = 0;
            svi.validAccount = "";
            svi.validAccount1 = "";
            svi.reason = "No QC needed.";
            svi.validResult = 0;
            svi.receive_order = epd.pur_order;
            svi.purch_d_id = epd.ID;
            svi.wms_state = (int)enumReceiveStockDetailStatus.已验收;
            svi.batch = "";
            svi.product_date = "";
            svi.save_date = "";
            svi.zhitongPartion = cachePartion;
            svi.validResult = cachePartion > 0 ? (int)enumWhType.越仓收货区 : (int)getWhType(orderType);
            svi.whType = svi.validResult;
            string skuCode = string.Format("{0}:{1};", "goodsId", epd.goods_id);
            int skuId = new lLot().getSKU(skuCode, null, wg.lotId, epd.goods_id, wg.ownerCode);
            svi.skuCode = skuCode;
            svi.skuId = skuId;
            validIn(svi, true);
        }
        private enumWhType getWhType(enumInOrderType orderType)
        {
            enumWhType whType = enumWhType.合格库;
            switch (orderType)
            {
                case enumInOrderType.采购入库:
                    whType = enumWhType.合格库;
                    break;
                case enumInOrderType.调拨入库:
                    whType = enumWhType.合格库;
                    break;
                case enumInOrderType.销售退仓:
                    whType = enumWhType.退货库;
                    break;
                case enumInOrderType.召回返仓:
                    whType = enumWhType.合格库;
                    break;
            }
            return whType;
        }
        /// 
        /// 按单收货
        /// 
        /// 
        /// 收货 or 拒收
        /// 
        /// 
        internal string receiveByOrder(string orderNo, int inType, string inRemark, int shipId, bool isCache, int cachePartion)
        {
            Erp_purch ep = new Erp_purch(orderNo);
            DataTable dt = getRequestInDetail(orderNo);
            List lst = new List();
            foreach (DataRow dr in dt.Rows)
            {
                lst.Add( new Erp_purch_d(dr));
            } 
            return receiveDetailsPre((enumInOrderType)inType, null, 0, ep.vender, lst);  
            /*
            decimal rcNumber = 0;
            decimal rjNumber = 0;
            Erp_purch_d epd;
            bool isNeedQc = false;
            enumReceiveStockDetailStatus nextState = enumReceiveStockDetailStatus.待验收;
            WmsGoods wg;
            using (TransactionScope scope = new TransactionScope())
            {
                foreach (DataRow dr in dt.Rows)
                {
                    epd = new Erp_purch_d(dr);
                    nextState = enumReceiveStockDetailStatus.待验收;
                    epd.storeType = isCache ? 0 : 1;
                    epd.zhitongPartion = cachePartion;
                    wg = new WmsGoods(epd.goods_id);
                    if (!wg.isQc) //跳过验收界面,直接进入入库环节
                    {
                        nextState = enumReceiveStockDetailStatus.已验收;
                        //create inrequest
                        createInrequest4NoQc((enumInOrderType)ep.orderType, epd, isCache, cachePartion, wg);
                    }
                    else
                    {
                        isNeedQc = true;
                    }
                    rcNumber = inType == 0 ? epd.count - epd.receiveCount : 0;
                    rjNumber = inType == 1 ? epd.count - epd.receiveCount : 0;
                    epd.arriveCount += rcNumber + rjNumber;
                    epd.receiveCount += rcNumber;
                    epd.rejectCount += rjNumber;
                    epd.wms_state = inType == 0 ? (int)nextState : (int)enumReceiveStockDetailStatus.拒收;
                    epd.operater = this.operId;
                    epd.Update();
                    Erp_purch_receive_log erl = new Erp_purch_receive_log();
                    erl.arriveCount = rcNumber + rjNumber;
                    erl.receiveCount = rcNumber;
                    erl.rejectCount = rjNumber;
                    erl.receiveRemark = inRemark;
                    erl.shipId = shipId;
                    erl.operater = this.operId;
                    erl.pur_order = epd.pur_order;
                    erl.purch_d_id = epd.ID;
                    erl.Add();
                }
                enumInStockOrderStatus nextphState = isNeedQc ? enumInStockOrderStatus.待验收 : enumInStockOrderStatus.已验收;
                ep.wms_state = inType == 1 ? (int)enumInStockOrderStatus.已拒收 : (int)nextphState;
                ep.operater = this.operId;
                ep.receiveRemark = inRemark;
                ep.Update();
                scope.Complete();
            }
            return true;
            */
        }
        internal DataSet queryValidation(string querystr, int rownumStart, int rownumEnd)
        {
            return erpPurchObj.queryValidation(querystr, rownumStart, rownumEnd);
        }
        internal DataTable getValidedInDetail(string orderNo, int status = -1)
        {
            return erpPurchObj.getValidedInDetail(orderNo, status);
        }
        internal bool validIn(StructsValideIn validIn, bool isInStockNow = false, int recommandWareHouse = 0, int purch_d_id = 0, bool isOnce = false)
        {
            logIn.Debug("purch_d_id :" + purch_d_id + ", to valid: " +Util.getJson( validIn));
            using (TransactionScope scope = new TransactionScope())
            {
                Erp_purch_d epd = new Erp_purch_d(validIn.purch_d_id);
                Erp_purch ep = new Erp_purch(epd.pur_order);
                if (validIn.whType == (int)enumWhType.不合格库)
                {
                    if (WmsConstants.IN_STOCK_BAD_COUNTIN_VALID)
                    {
                        epd.validCount += validIn.valid_count;
                    }
                    epd.rejectCount += validIn.valid_count;
                }
                else
                {
                    epd.validCount += validIn.valid_count;
                }
               
                decimal acount = epd.count  /*-epd.receiveCount*/ - epd.rejectCount;
                epd.wms_state = epd.validCount >= acount /*epd.receiveCount*/ ? (int)enumReceiveStockDetailStatus.已验收 : epd.wms_state;
               
                epd.operater = this.operId;
                epd.Update();
               // if (epd.wms_state == (int)enumReceiveStockDetailStatus.已验收 && validIn.preInOrder!=null) //到货可能大于验收数量,所以不做此限制
                {
                   WmsFlow flow = new WmsFlow(validIn.preInOrder);
                    /*
                     * flow.finishedCnt += flow.finishedCnt < flow.taskCnt ? 1 : 0;
                     if (flow.finishedCnt >= flow.taskCnt)
                     {
                         flow.state = (int)enumFlowTaskStatus.已完成;
                     }
                     flow.finishedCnt = flow.finishedCnt > flow.taskCnt ? flow.taskCnt : flow.finishedCnt;
                     */
                    WmsGoods wg = new WmsGoods(epd.goods_id);
                    logIn.Debug(string.Format("wg name {0}, wg bigcount {1}, wg iszhitong {2}",wg.goodsName,wg.bigCount,wg.isZhitong));
                    logIn.Debug(wg);
                    decimal finishedPcs = validIn.valid_count / wg.bigCount;
                    finishedPcs= validIn.outPickDetailId > 0  //直通
                      ? (validIn.flowNo.StartsWith("zt") //强制完验
                          ? 1: finishedPcs)
                      : finishedPcs;
                    flow.finishedTasksPlus(operId, finishedPcs, validIn.outPickDetailId>0 || wg.isZhitong);// 直通商品
                   
                }
            
                if (String.IsNullOrEmpty(validIn.batch))
                {
                    validIn.batch = validIn.product_date;
                }
                bool isAllProceed = true;
                DataTable dt = getRequestInDetail(epd.pur_order);
                foreach (DataRow dr in dt.Rows)
                {
                    //  if ( Convert.ToInt32(dr["wms_state"].ToString()) != (int)enumReceiveStockDetailStatus.待入库)
                    if ( Convert.ToInt32(dr["wms_state"].ToString()) == (int)enumReceiveStockDetailStatus.待验收
                        ||  Convert.ToInt32(dr["wms_state"].ToString()) == (int)enumReceiveStockDetailStatus.待收货
                        )
                    {
                        isAllProceed = false;
                        break;
                    }
                }
                if (isAllProceed)
                {
                    ep.wms_state = (int)enumInStockOrderStatus.已验收;
                    ep.operater = this.operId;
                    ep.Update();
                    if (ep.orderType == (int)enumOrderType.无单入库)
                    {
                        WmsOrderRequest wor = new WmsOrderRequest(ep.pur_order);
                        wor.state =(int) enumOrderStatus.已完成;
                        wor.Update();
                    }
                }
                if (validIn.validResult == (int)enumWhType.虚拟库
                    || validIn.isZhitong && purch_d_id == 0)
                {
                    scope.Complete();
                    if (isAllProceed)
                    {
                       //  noticeErpValiIn(ep); // use the notice in preInDone operation
                    }
                        return true;
                }
                Erp_receiveValidDetail erd = new Erp_receiveValidDetail();
                erd.flowNo = validIn.flowNo;
                erd.batch = validIn.batch;
                erd.goods_id = validIn.goods_id;
                erd.operater = validIn.validby;// this.operId;
                erd.purch_d_id = validIn.purch_d_id;
                erd.receive_order = validIn.receive_order;
                erd.reason = validIn.reason;
                erd.seeds_count = validIn.seeds_count;
                erd.valid_count = validIn.valid_count;
                erd.productDate = validIn.product_date;
                erd.validDate = validIn.save_date;
                erd.validby = validIn.validby;
                erd.validby1 = validIn.validby1;
                erd.validResult = validIn.validResult;
                erd.whType = validIn.whType;// validIn.zhitongPartion == 0 ? (int)getWhType((enumInOrderType)ep.orderType) : erd.validResult;
                erd.wms_state = validIn.wms_state;
                erd.erp_state = validIn.erp_state;
                erd.preInOrder = String.IsNullOrEmpty(validIn.preInOrder) ? "" : validIn.preInOrder;
                erd.skuId = validIn.skuId;
                erd.skuCode = validIn.skuCode;
                erd.partion = validIn.zhitongPartion;
                erd.validbyTime = erd.getDateTime();
                erd.validbyTime1 = erd.validbyTime;
                erd.poNo = validIn.poNo;
                erd.outDetailId = validIn.outPickDetailId;
                erd.price=validIn.price;
                erd.Add();
                //to create/update in stock request in wms.
                WmsInRequest wir = new WmsInRequest(validIn.receive_order);
                if (wir.ID == 0)
                {
                    // create new wmsInRequest
                    dt = ep.getRequestIn(ep.pur_order);
                    foreach (DataRow dr in dt.Rows)
                    {
                        wir = new WmsInRequest(dr);
                        break;
                    }
                    wir.preInOrder = validIn.receive_order;
                    wir.operater = this.operId;
                    wir.orderType = 0;
                    wir.state = (int)enumInStockOrderStatus.已验收;
                    wir.Add();
                }
                else {
                    wir.state = (int)enumInStockOrderStatus.已验收;
                    wir.Update();
                }
                dt = erd.getRequestValidInDetail(erd.ID); // 一条验收记录对应一个WmsInRequestDetail记录
                foreach (DataRow dr in dt.Rows)
                {
                    WmsInRequestDetail wid = new WmsInRequestDetail(dr);
                    wid.operater = this.operId;
               
                    wid.state = validIn.isOnLoc ?  (int)enumInStockDetailStatus.上架完成: (int)enumInStockDetailStatus.未分配货位 ;
                    wid.whType = validIn.whType;
                    wid.entid = epd.entid;
                    wid.outDetailId = validIn.outPickDetailId;
                   
                    wid.Add();
                    if (isInStockNow)
                    {
                        logIn.Debug(string.Format(" validin is on loc {0}", validIn.isOnLoc));
                        if (validIn.isOnLoc) {
                            wid.countIn = wid.validCount;
                            WmsStock stock = new WmsStock(validIn.locId,wid.skuId,wid.goodsId);
                            logIn.Debug("to on shelf stock: " + stock.ToString());
                            stock.count += wid.countIn;
                            if (stock.ID == 0)
                            {
                                stock.locationId = validIn.locId;
                                stock.goodsId = wid.goodsId;
                                stock.batch = wid.batch;
                                stock.productDate = wid.productDate;
                                stock.validDate = wid.validDate;
                                stock.validationTerm = 1;
                                stock.operater = this.operId;
                                stock.state = (int)enumStockLocationStatus.正常;
                                stock.skuCode = wid.skuCode;
                                stock.skuId = wid.skuId;
                                stock.maintainDate = stock.getDateTime();
                                if (String.IsNullOrEmpty(stock.batch))
                                {
                                    stock.batch = wid.productDate;
                                }
                                  stock.Add();
                            }
                            else
                            {
                                  stock.Update();
                            }
                               
                        
                            logStock(wid, stock, wid.countIn, enumInStoreType.直接上架);
                       
                            updateErpDetail(wid.ID);
                        } else
                        {
                            try
                            {
                                requestDetailIn(wir, wid, recommandWareHouse,isOnce);
                            }
                            catch (Exception er)
                            {
                                scope.Dispose();
                                logIn.Error(er);
                                throw er;
                                // return false;
                            } }
                    }
                    break;
                }
                scope.Complete();
                if (isAllProceed)
                {
                   // noticeErpValiIn(ep); // use the notice in preInDone operation
                }
            }
            return true;
        }
        public string retryNoticeErpValidIn(bool isForce=false)
        {
            //enumErpOrderStatus status = enumErpOrderStatus.通知失败;
            DataTable dt = erpPurchObj.getByErpNoticeFailure(isForce);
            if (dt.Rows.Count > 0)
            {
                logERP.Debug(string.Format(" to retry notice ERP purch orders  count {0} ", dt.Rows.Count));
                foreach (DataRow dr in dt.Rows)
                {
                    noticeErpValiIn(new Erp_purch(dr));
                    Thread.Sleep(2500);
                }
            }
              dt = getWmsInRequest.getToNoticeErpLst();
            if (dt.Rows.Count > 0)
            {
                logERP.Debug(string.Format(" to notice ERP purch orders count {0} ", dt.Rows.Count));
                foreach (DataRow dr in dt.Rows)
                {
                    noticeErpValiIn(new Erp_purch(new WmsInRequest(dr).preInOrder));
                    Thread.Sleep(2500);
                }
            }
            
            return "";
        }
        public void noticeErpValiIn(Erp_purch pur_order)
        {
            Thread threadPreProcess = new Thread(new ParameterizedThreadStart(noticeInErp));
            threadPreProcess.IsBackground = true;
            threadPreProcess.Start(pur_order);
        }
        class Res
        {
            public Res()
            {
            }
            string status;
            string messag;
            string data;
            public string Status {
                get {
                    return status;
                }
            }
            public string Messag
            {
                get
                {
                    return messag;
                }
            }
            public string Data
            {
                get
                {
                    return data;
                }
            }
        }
        private void noticeInErp(Object purchObj)
        {
            if (!WmsConstants.ERP_NOTICE_STOCK_IN)
            {
                return;
            }
            // string orderNo = "ZCCGR230106-0027";
            string url = string.Format(WmsConstants.ERP_API_ORDER_NOTICE, ((Erp_purch)purchObj).pur_order, (int)enumErpOrderType.入库);
            //   logIn.Error("WmsConstants.ERP_API_ORDER_NOTICE  " + WmsConstants.ERP_API_ORDER_NOTICE);
            //   logIn.Error("WmsConstants.ERP_API_KEY  " + WmsConstants.ERP_API_KEY);
            //  logIn.Error(url); 
            try
            {
                HttpWebRequest webReq = getErpRequest(url);
                System.Net.HttpWebResponse response;
                response = (System.Net.HttpWebResponse)webReq.GetResponse();
                System.IO.StreamReader myreader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8);
                string responseText = myreader.ReadToEnd();
                myreader.Close();
                //logTest.Debug(((Erp_purch)purchObj).pur_order + " (enumErpOrderType.入库),notice erp response code " + response.StatusCode);
                // logIn.Debug(responseText);
                logERP.Debug(string.Format(" notice ERP purch order {0},response {1}", ((Erp_purch)purchObj).pur_order, responseText));
                ((Erp_purch)purchObj).erp_state = (int)enumErpOrderStatus.通知失败;
                ((Erp_purch)purchObj).wms_state = (int)enumInStockOrderStatus.完验;  //辣得叫 不存在多次收货情况,到货通知单完验
              
                WmsInRequest win = new WmsInRequest(((Erp_purch)purchObj).pur_order);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Newtonsoft.Json.Linq.JObject jo = (JObject)JsonConvert.DeserializeObject(responseText);
                    // logIn.Debug(" jo obj  :  " +jo.GetValue("status"));
                    //  Res  res = (Res)JsonConvert.DeserializeObject(responseText,typeof(Res));
                    //   logIn.Debug(" res obj  :  " + Util.getJson(res));
                    if (jo.GetValue("status").ToString() == "SUCCESS")// || res.Status== "SUCCESS")
                    {
                        ((Erp_purch)purchObj).erp_state = (int)enumErpOrderStatus.通知成功;
                        ((Erp_purch)purchObj).wms_state = (int)enumInStockOrderStatus.完结回传ERP;
                      
                        win.state = (int)enumInStockOrderStatus.完结回传ERP;
                        win.Update();
                    }
                    // ((Erp_purch)purchObj).ext1 = res.Messag;
                }
                logIn.Debug(" to update purch order status to:  " + (enumInStockOrderStatus)((Erp_purch)purchObj).wms_state);
                try
                {
                    ((Erp_purch)purchObj).Update();
                    if ( ((Erp_purch)purchObj).orderType == (int)enumOrderType.无单入库)
                    {
                        WmsOrderRequest wor = new WmsOrderRequest(((Erp_purch)purchObj).pur_order);
                        wor.state = ((Erp_purch)purchObj).erp_state;
                        wor.Update();
                    }
                }
                catch (Exception ex)
                {
                    logIn.Debug("通知状态更新失败");
                    logIn.Error(ex);
                }
            }
            catch (Exception e)
            {
                logIn.Error(e);
            }
        }
        internal DataTable getReceivePreSumByVender(string venderId)
        {
            return erpPurchObj.getReceivePreSumByVender(venderId);
        }
        internal DataTable getReceivePreSumByVenderNotValided(string venderId)
        {
            return erpPurchObj.getReceivePreSumByVenderNotValided(venderId);
        }
        internal DataTable getReceivePreSumByPreNo(string preNo)
        {
            return erpPurchObj.getReceivePreSumByPreNo(preNo);
        }
        internal DataTable getReceiveHistory(string purOrderNo)
        {
            return erpPurchObj.getReceiveHistory(purOrderNo);
        }
        internal DataTable getReceiveMuiltiHistory(string purOrderNo)
        {
            return erpPurchObj.getReceiveMuiltiHistory(purOrderNo);
        }
         
        internal int newShipInfo(structShip ship)
        {
            Erp_purch_ship eps = new Erp_purch_ship();
            eps.shipOrder = String.IsNullOrEmpty(ship.shipOrder) ? "" : ship.shipOrder;
            eps.company = String.IsNullOrEmpty(ship.company) ? "" : ship.company;
            eps.driverID = String.IsNullOrEmpty(ship.driverID) ? "" : ship.driverID;
            eps.driverName = String.IsNullOrEmpty(ship.driverName) ? "" : ship.driverName;
            eps.driverPhone = String.IsNullOrEmpty(ship.driverPhone) ? "" : ship.driverPhone;
            eps.operater = this.operId;
            eps.remark = String.IsNullOrEmpty(ship.remark) ? "" : ship.remark;
            eps.temperature = ship.temperature;
            eps.veNumber = String.IsNullOrEmpty(ship.veNumber) ? "" : ship.veNumber;
            eps.Add();
            return eps.ID;
        }
        internal DataSet getShipRecs(string querystr, int rownumStart, int rownumEnd)
        {
            return erpPurchShipObj.QueryPages(querystr, rownumStart, rownumEnd);
        }
        internal DataSet getReceiveRecs(string querystr, int rownumStart, int rownumEnd)
        {
            return erpPurchObj.getReceiveRecs(querystr, rownumStart, rownumEnd);
        }
        internal DataTable getShipReceiveDetail(string shipNo)
        {
            return erpPurchShipObj.getShipReceiveDetail(shipNo);
        }
        internal DataTable getShipReceiveDetail(int shipId)
        {
            return erpPurchShipObj.getShipReceiveDetail(shipId);
        }
        internal DataTable getShipDetail(string shipNo)
        {
            return erpPurchShipObj.getShipDetail(shipNo);
        }
        internal DataSet queryValidationLog(string querystr, int rownumStart, int rownumEnd)
        {
            return erpPurchObj.queryValidationLog(querystr, rownumStart, rownumEnd);
        }
        //----多笔订单一起验收
        internal string receiveDetailsPre(enumInOrderType ordeType, int[] ids, int shipId, string venderId,  List lst=null)
        {  
            log.Debug( String.Format("receiveDetailsPre, venderId {0}, 明细数量 {1} ", venderId, ids!=null? ids.Length : lst!=null? lst.Count:0));
            string preNo = "";
            if (lst == null)
            {
                lst = new List();
                foreach (int id in ids)
                {
                    lst.Add(new Erp_purch_d(id));
                }
            }
            if (lst == null || lst.Count==0)
            {
                log.Debug(" 没有 收货明细。。。。。");
                return "";
            }
         
            //using (TransactionScope scope = new TransactionScope())
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions()
            {
                IsolationLevel = System.Transactions.IsolationLevel.Serializable,
                Timeout = new TimeSpan(0, 30, 0)
            }
                  ))
            {
                try
                {
                    foreach (Erp_purch_d pd in lst)
                    {
                        receiveDetailPre(pd.pur_order, ordeType, pd.ID, pd.count, "", shipId);
                        pd.wms_state = (int)enumReceiveStockDetailStatus.待验收;
                        pd.Update();
                        
                    }
                    logIn.Debug(" receiveDetailPre done.... begin to postPreIn");
                    preNo = postPreIn(venderId, shipId);
                    logIn.Debug("postPreIn done.... begin to recieve auto");
                    WmsFlow wmsflow = new WmsFlow();
                    wmsflow.operater = operId;
                    wmsflow.orderNo = preNo;
                    wmsflow.flowNo = preNo;
                    wmsflow.type = (int)EnumFlowTaskType.入库验收;
                    wmsflow.typeName =EnumFlowTaskType.入库验收.ToString();
                    wmsflow.task = preNo;// Util.getOrderNo(enumCreateOrderType.pickJobNo, _obj.getNextSeq(enumCreateOrderType.pickJobNo)); 
                   // wmsflow.taskPartion = r.partion;
                   // wmsflow.toPartion = r.partion;
                    // wmsflow.toLocationId = r.locationId; 
                    wmsflow.taskCnt = lst.Count;
                     
                    wmsflow.Add();
              
                    /*
                    foreach (Erp_purch_d pd in lst)
                    {
                        receivePreDetail(preNo, pd.goods_id, pd.count, pd.count, 0, "", false, 0, 0);
                    }
                    */
                }
                catch (Exception er)
                {
                    logIn.Error(er);
                    scope.Dispose();
                    //  return er.Message;
                    throw er;
                }
                scope.Complete();
            }
            return preNo;
        }
        /// 
        /// 条目预收
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        internal bool receiveDetailPre(string orderNo, enumInOrderType ordeType, int id, decimal arriveNumber, string inRemark, int shipId)
        {
            LogHelper.debug(GetType(), String.Format("receiveDetailPre, orderNo {0}, puch_d_id {1},arriveNumber {2}", orderNo, id, arriveNumber));
            //新到arriveNumber 允许负值,最终预到明细的arriveCount不可负值
            // Erp_purch_d ed = new Erp_purch_d(id); 
            Erp_purch_receive_pre eprp = new Erp_purch_receive_pre();
            eprp.getNewDetailByOrderDetailId(id);
            eprp.mem = inRemark;
            eprp.pur_order = orderNo;
            eprp.purch_d_id = id;
            if (eprp.ID > 0)
            {
               logIn.Debug( String.Format("明细预到数量累积 "));
                eprp.arriveCount += arriveNumber;   //同一个采购单下,未生成预到单的,明细预到数量累积  ,同一个预到单号下,预到明细ID唯一,预到数量不累加。
                                                    //prp.arriveCount = eprp.arriveCount > 0 ? eprp.arriveCount : 0;
                if (eprp.arriveCount <= 0)
                {
                    return eprp.Delete() > 0;
                }
                return eprp.Update() > 1;
            }
            else if (arriveNumber > 0)
            {
               logIn.Debug(String.Format("新增预到明细数量 "));
                eprp.orderType = (int)ordeType;
                eprp.arriveCount = arriveNumber;
                 
                return eprp.Add() > 1;
            }
            return false;
        }
        /// 
        /// 整单预收
        /// 
        /// 
        /// 
        /// 
        /// 
        internal string receiveByOrderPre(string orderNo,string vender, enumInOrderType orderType, string inRemark, int shipId)
        {
           logIn.Debug( String.Format("receiveByOrderPre, orderNo {0},vender {1},orderType {2}", orderNo,vender,orderType.ToString()));
            DataTable dt = getRequestInDetail(orderNo);
          
   
         
            List lst = new List();
            foreach (DataRow dr in dt.Rows)
            {
                lst.Add( new Erp_purch_d(dr));
              
                 
            }
            logIn.Debug( String.Format("receiveByOrderPre, 开始处理明细...数量{0}", lst.Count));
            string preNo = receiveDetailsPre(orderType, null, 0, vender, lst);
            logIn.Debug( String.Format("receiveByOrderPre,处理完毕......")+ preNo);
            return preNo;
        }
        internal DataTable queryPurchDetailByVender(string venderId, int status)
        {
            return erpPurchObj.queryPurchDetailByVender(venderId, status);
        }
        internal string postPreIn(string venderId, int shipid)
        {
            string preInNo = Util.getOrderNo(enumCreateOrderType.preInOrder, preInObj.getNextSeq(enumCreateOrderType.preInOrder));
            logIn.Debug("get preinNo :" + preInNo);
            if (preInObj.postPreIn(venderId, preInNo, shipid))
            {
                if (WmsConstants.IN_STOCK_PREIN_AUTO_RECEIVE)
                {
                    /* try {
                         receivePreDetailAuto(preInNo);
                     } catch (Exception ex) {
                         logIn.Error(ex);
                         return "";
                     }
                     */  
                    
                  //  throw new Exception("TEST事务(进程 ID 57)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务");
                    receivePreDetailAuto(preInNo);
                  
                }
                return preInNo;
            }
            return "";
        }
        internal bool receivePreDetailAuto(string preInNo)
        {
            DataTable dt = preInObj.getDetailByOrder(preInNo);
            DataView dv = dt.DefaultView;
            dv.Sort = "count1 asc";
            decimal epdReceiveCount = 0;
            decimal epdMax = 0;
            bool ret = false;
            Erp_purch_d epd;
            Erp_purch_receive_pre eprd;
            List stks = null;
            if (WmsConstants.OUT_STOCK_LACK_VIR_IN_AUTO && WmsConstants.OUT_STOCK_LACK_VIR_OUT_AUTO)  //扣除预出部分
            {
                stks = new WmsStock().getLackStockObjs();
            }
            foreach (DataRowView dr in dv)
            {
                epd = new Erp_purch_d(dr.Row);
                eprd = new Erp_purch_receive_pre(preInNo, epd.ID);
                // epdMax = epd.count - epd.rejectCount - epd.receiveCount;
                decimal receiveNumber = eprd.arriveCount;
                decimal arriveNumber = eprd.arriveCount;
                epdMax = eprd.arriveCount - eprd.receiveCount;
                if (epdMax == 0)
                {
                    continue;
                }
                if (epdMax >= receiveNumber)
                {
                    epdReceiveCount = receiveNumber;
                }
                else
                {
                    epdReceiveCount = epdMax;
                }
                //   using (TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        ret = receiveDetail(preInNo, epd.ID, arriveNumber, epdReceiveCount, 0, "AutoReceive", eprd.shipId, false, 0, 100);
                        ret = ret && eprd.receive(preInNo, epd.ID, epdReceiveCount, operId) > 0;
                    }
                    catch (Exception er)
                    {
                        logIn.Error(er);
                        throw er;
                    }
                    //    scope.Complete();
                }
                receiveNumber = receiveNumber - epdReceiveCount;
                if (WmsConstants.OUT_STOCK_LACK_VIR_IN_AUTO)  //扣除预出部分
                {
                    foreach (WmsStock st in stks)
                    {
                        if (epd.goods_id.Equals(st.goodsId))
                        {
                            decimal lackCnt = epd.arriveCount > st.virtialCount ? st.virtialCount : epd.arriveCount;
                            validIn(preInNo, "autoFlow", epd.goods_id, lackCnt, 0, null, true, false, true);
                        }
                    }
                }
            }
            return ret;
        }
        internal DataTable getPreInDetail(string preInNo)
        {
            return preInObj.getPreInDetailWince(preInNo);
        }
        internal DataTable getPreInSumary(string preInNo)
        {
            return preInObj.getPreInSumary(preInNo);
        }
        /// 
        /// pda  收货,基于预收数据
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        internal bool receivePreDetail(string preInNo, string goodsId, decimal arriveNumber, decimal receiveNumber,
            int inType, string inRemark, bool isCache, int cachePartion, decimal temperature)
        {
            DataTable dt = preInObj.getDetailByOrder(preInNo);
            DataView dv = dt.DefaultView;
            dv.RowFilter = string.Format("goodsId ='{0}' ", goodsId);
            dv.Sort = "count1 asc";
            decimal epdReceiveCount = 0;
            decimal epdMax = 0;
            bool ret = false;
            Erp_purch_d epd;
            Erp_purch_receive_pre eprd;
            foreach (DataRowView dr in dv)
            {
                epd = new Erp_purch_d(dr.Row);
                eprd = new Erp_purch_receive_pre(preInNo, epd.ID);
                // epdMax = epd.count - epd.rejectCount - epd.receiveCount;
                epdMax = eprd.arriveCount - eprd.receiveCount;
                if (epdMax == 0)
                {
                    continue;
                }
                if (epdMax >= receiveNumber)
                {
                    epdReceiveCount = receiveNumber;
                }
                else
                {
                    epdReceiveCount = epdMax;
                }
                using (TransactionScope scope = new TransactionScope())
                {
                    ret = receiveDetail(preInNo, epd.ID, arriveNumber, epdReceiveCount, inType, inRemark, eprd.shipId, isCache, cachePartion, temperature);
                    ret = ret && eprd.receive(preInNo, epd.ID, epdReceiveCount, operId) > 0;
                    scope.Complete();
                }
                receiveNumber = receiveNumber - epdReceiveCount;
                if (receiveNumber <= 0)
                {
                    break;
                }
            }
            return ret;
        }
        public decimal getValidSeedsCnt(string goodsId, decimal batchCount)
        {
            WmsGoods wg = new WmsGoods(goodsId);
            decimal bigcount = wg.bigCount;
            if (bigcount == 0)
            {
                return -1;
            }
            decimal bulkcnt = batchCount % bigcount;
            decimal boxcnt = (batchCount - bulkcnt) / bigcount;
            decimal seedsStep = WmsConstants.GOODS_IN_VALID_SEEDS_BOXS_STEP;
            decimal minStep = WmsConstants.GOODS_IN_VALID_SEEDS_BOXS_STEP_MIN; ;
            decimal stepFactor = WmsConstants.GOODS_IN_VALID_SEEDS_BOXS_STEP_FACTOR; ;
            decimal seedsCount = 0;
            if (boxcnt < seedsStep)
            {
                if (boxcnt > minStep)
                {
                    seedsCount = minStep;
                }
                else
                {
                    seedsCount = boxcnt;
                }
            }
            else
            {
                seedsCount = minStep + Math.Ceiling((boxcnt - seedsStep) / seedsStep) * stepFactor;
            }
            seedsCount = seedsCount > 0 ? seedsCount : 1;
            return seedsCount;
        }
        internal DataTable getGoodsPackByBarcode(string barcode)
        {
            return new WmsGoods().getGoodsBybarcod(barcode);
        }
        internal DataTable getGoodsDetailByBarcode(string barcode)
        {
         //   log.Debug(" to check temp token authorition, userid is " + operId);
            //if (ConstAuthourity.havePermission(operId, WmsConstants.SPECIAL_VALID_NEAR_EXPIRED))
            {
            }
                return new WmsGoods().getGoodsDetailBybarcode(barcode);
        }
        internal DataTable getReceiveDetailByBarcode(string preInOrder, string barcode)
        {
            return this.preInObj.getReceiveDetailByBarcode(preInOrder, barcode);
        }
        internal enumValidInResult validInZhitong(string preInNo, string goodsId, decimal batchCount, decimal seedsCnt, Dictionary skuValues, int purch_d_id, int outDetailId)
        {
            enumValidInResult result = validIn(preInNo, "ZT666", goodsId, batchCount, 0, skuValues, true, true, false, 0, 0, false, false, true, null, 0, outDetailId, purch_d_id);
            return result;
        }
        internal enumValidInResult validIn(string preInNo, string flowNo, string goodsId, decimal batchCount, decimal seedsCnt,
            Dictionary skuValues, bool isPass, bool isIsuLocations, bool isVirtualIn, int secondValidUser = 0, int recommandWareHouse = 0,
            bool ischeckLeftValidDays = true, bool isFlowUni = false, bool isZhitong = false, string pickOrderNo = null, int zhitongPartion = 0, 
            int outPickDetailId = 0, int purch_d_id = 0,bool isOnce=false)
        {
            logIn.Debug(string.Format("start validIn preInNo {0},flowNo {1}, goodsId {2},  batchCount {3}, isZhitong: {4} , outPickDetailId :{5}, puch_d_id :{6}"
                , preInNo, flowNo, goodsId, batchCount, isZhitong, outPickDetailId, purch_d_id));
            if (preInObj.getDetailByOrder(preInNo, (int)enumInStockOrderStatus.完验).Rows.Count > 0)
            {
                return enumValidInResult.已完验;
            }
            if (isFlowUni)
            {
                DataTable tmp = getWmsInRequest.getInPortDetails(preInNo, flowNo);
                if (tmp.Rows.Count > 0)
                {
                    return enumValidInResult.流水码已使用;
                }
            }
            WmsFlow flow = new WmsFlow();
           if(flow.isStarted(preInNo, flowNo))
            {
                return enumValidInResult.已封板;
            }
            //when is virtual In , check if the stock can take in the goods, 必须现有出借,有赤字库存存在则可以入库冲抵负库存
            WmsGoods wg = new WmsGoods(goodsId);
            if (wg.ID == 0)
            {
                throw new Exception(string.Format("请维护 '{0}' 的商品类型", goodsId));
            }
            if (wg.bigCount == 0)
            {
                throw new DeiNiuException(string.Format("请维护 '{0}' 的大包装数量 ", goodsId));
            }
            if (wg.goodsType == 0)
            {
                throw new DeiNiuException(string.Format("请维护 '{0}' 的商品类型", goodsId));
            }
            decimal epdValidCount = 0;
            decimal epdMax = 0;
            bool ret = false;
            Erp_purch_d epd;
            Erp_purch_receive_pre eprd;
            string skuCode = "";
            int skuId = 0;
            StructsValideIn svi = new StructsValideIn();
            WmsLocation loc = new WmsLocation(flowNo);
            /*
              bool isOnLoc = loc.ID > 0;
              if (isOnLoc) //货已上架,入库记账
              {
                  svi.isOnLoc = true;
                  svi.locId = flowNo;
              }
              */
            svi.isOnLoc = loc.ID > 0;
            svi.locId = flowNo;
            WmsStock stkVirtial = new WmsStock();
            if (isVirtualIn)
            {
                stkVirtial.getVirStock(goodsId);
                decimal lackCnt = stkVirtial.countOut - stkVirtial.count; 
                if (lackCnt <= 0 || stkVirtial.ID==0)
                { 
                     return enumValidInResult.无虚拟库抵扣; 
                }
                batchCount = lackCnt > batchCount ? batchCount : lackCnt;  
                isIsuLocations = false;
            }
            try
            {
                if (!isVirtualIn && !isZhitong && skuValues.ContainsKey(WmsConstants.SKU_RESEVRED_PRDDATE_ATTNAME))
                {
                    if (skuValues.ContainsKey(WmsConstants.SKU_RESEVRED_EXPIREDATE_ATTNAME))
                    {
                        String pdate = skuValues[WmsConstants.SKU_RESEVRED_PRDDATE_ATTNAME];
                        logIn.Debug("product date is :" + pdate);
                     
                        DateTime validDate = getValidDate(pdate, goodsId); //Util.pareseDateString(skuValues[WmsConstants.SKU_RESEVRED_EXPIREDATE_ATTNAME]);
                        if (wg.expiryDays > 0)  //效期无限长
                        {
                            // return enumValidInResult.请维护效期天数;
                            DateTime prdDate = Util.pareseDateString(pdate);
                            if (prdDate >= validDate
                              || prdDate > DateTime.Now
                              || validDate < DateTime.Now)
                            {
                                return enumValidInResult.效期错误;
                            }
                            int leftDays = getLeftDays(pdate, goodsId);
                            if (ischeckLeftValidDays)
                            {
                                /*
                               if( leftDays < WmsConstants.IN_STOCK_LEFT_VALID_DAYS)
                                   return enumValidInResult.临期商品;
                               */
                                if (leftDays <= 0)
                                {
                                    return enumValidInResult.过期商品;
                                }
                                if (leftDays < WmsConstants.IN_STOCK_LEFT_VALID_FACTOR * wg.expiryDays)
                                {
                                   
                                    
                                    if(!havePermission( WmsConstants.SPECIAL_VALID_NEAR_EXPIRED))                                    
                                       return enumValidInResult.临期商品;
                                }
                                    
                            }
                        }
                        skuValues[WmsConstants.SKU_RESEVRED_PRDDATE_ATTNAME] = Util.getShortDateString(skuValues[WmsConstants.SKU_RESEVRED_PRDDATE_ATTNAME]);
                        skuValues[WmsConstants.SKU_RESEVRED_EXPIREDATE_ATTNAME] = Util.getShortDateString(validDate.ToShortDateString());
                        if (skuValues.ContainsKey(WmsConstants.SKU_RESEVRED_BATCH_ATTNAME))
                        {
                            skuValues[WmsConstants.SKU_RESEVRED_BATCH_ATTNAME] = String.IsNullOrEmpty(skuValues[WmsConstants.SKU_RESEVRED_BATCH_ATTNAME]) ? pdate : skuValues[WmsConstants.SKU_RESEVRED_BATCH_ATTNAME];
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LogHelper.debug(this.GetType(), "日期格式错误");
                LogHelper.WriteLog(this.GetType(), e);
                return enumValidInResult.效期错误;
            }
            svi.validby1 = secondValidUser;
            foreach (string key in skuValues.Keys)
            {
                logIn.Debug(string.Format("sku input  {0}:{1}", key, skuValues[key]));
            }
            if (isVirtualIn)
            {
                svi.validResult = (int)enumWhType.虚拟库;
            } else if (!isZhitong && isPass)
            {
                Dictionary dic = new lLot(operId).getSKU(skuValues[WmsConstants.SKU_RESEVRED_PRDDATE_ATTNAME], goodsId, skuValues[WmsConstants.SKU_RESEVRED_BATCH_ATTNAME]);
                foreach (int i in dic.Keys)
                {
                    skuId = i;
                    skuCode = dic[i];
                    break;
                }
                svi.validResult = (int)enumWhType.合格库;
            }
            else
            {
                svi.validResult = (int)enumWhType.不合格库;
            }
            svi.goods_id = goodsId;
            svi.validby = operId;
            svi.reason = "";
            //  svi.receive_order = preInNo; 
            svi.wms_state = (int)enumReceiveStockDetailStatus.已验收;
            svi.batch = "";
            svi.product_date = "";
            svi.save_date = "";
            svi.preInOrder = preInNo;
            svi.flowNo = flowNo;
            svi.outPickDetailId = outPickDetailId;
            svi.isZhitong = isZhitong;
            svi.isOnce = isOnce;
            if (skuValues != null)
            {
                 if (skuValues.ContainsKey(WmsConstants.SKU_RESEVRED_BATCH_ATTNAME))
                svi.batch = skuValues[WmsConstants.SKU_RESEVRED_BATCH_ATTNAME];
                if (skuValues.ContainsKey(WmsConstants.SKU_RESEVRED_PRDDATE_ATTNAME))
                    svi.product_date = skuValues[WmsConstants.SKU_RESEVRED_PRDDATE_ATTNAME];
                if (skuValues.ContainsKey(WmsConstants.SKU_RESEVRED_EXPIREDATE_ATTNAME))
                    svi.save_date = skuValues[WmsConstants.SKU_RESEVRED_EXPIREDATE_ATTNAME];
                if (skuValues.ContainsKey(WmsConstants.SKU_RESEVRED_ENTI_ATTNAME))
                    svi.entId = skuValues[WmsConstants.SKU_RESEVRED_ENTI_ATTNAME];
            }
          
            //svi.zhitongPartion = 1;
            //  svi.validResult = (int)enumWhType.越仓收货区;
            svi.skuCode = skuCode;
            svi.skuId = skuId;
             
            DataTable dtPredetails = preInObj.getDetailByOrder(preInNo);
            DataView dv = dtPredetails.DefaultView;
            dv.RowFilter = purch_d_id > 0 ? string.Format("id ='{0}' ", purch_d_id) : string.Format("goodsId ='{0}' ", goodsId);
            dv.Sort = "count1 asc";
            using (TransactionScope scope = new TransactionScope())
            {
                int i = 0;
                foreach (DataRowView dr in dv)    //每个明细按订单数量均摊验收数量 (不超收)
                {
                    i++;
                    epd = new Erp_purch_d(dr.Row);
                    eprd = new Erp_purch_receive_pre(preInNo, epd.ID);
                    if (epd.storeType == 1 && !isZhitong )
                    {
                     //  return enumValidInResult.直通商品不可入库上架;
                    }
                    logIn.Debug(" purch_d to valid: " + epd);
                    logIn.Debug(" eprd to valid: " + eprd);
                    if (eprd.state == (int)enumInStockOrderStatus.完验)
                    {
                       return enumValidInResult.已完验;
                      
                    }
                    // epdMax = epd.count - epd.rejectCount - epd.receiveCount;
                    svi.whType = (int)getWhType((enumInOrderType)eprd.orderType);
                    svi.poNo = epd.custPoNo;
                  
                    epdMax = eprd.receiveCount - eprd.validCount;
                    logIn.Debug(string.Format("epdMax {0}, eprd.receiveCount {1}, eprd.validCount{2}", epdMax, eprd.receiveCount, eprd.validCount));
                    if (epdMax >= batchCount)
                    {
                        epdValidCount = batchCount;
                    }
                    else
                    {
                        if (i == dv.Count) //if (epdMax <= 0)
                        {
                        
                           
                          //  decimal overRate = Math.Abs((epdMax - batchCount  )) * 100 / epdMax;
                            decimal overRate = ((eprd.validCount + batchCount) - eprd.receiveCount) * 100 / eprd.receiveCount;
                            
                            logIn.Debug(string.Format("epdMax {0} ,i {1}, dv.count {2}, 超收比例......... {3},  最大允许超收比例 {4}", epdMax,i,dv.Count, overRate, WmsConstants.IN_MAX_OVER_TIMES*100));
                            
                            if (!isZhitong 
                                //&& !wg.isWeightOut() 
                                && overRate / 100>WmsConstants.IN_MAX_OVER_TIMES
                                && !havePermission(WmsConstants.SPECIAL_AUTHS_SUPER))
                            {
                                logIn.Debug(string.Format("   超收比例 {0} >  最大允许比例 {1}", overRate / 100 , WmsConstants.IN_MAX_OVER_TIMES  ));
                                return enumValidInResult.超过最大允许收货数量;
                            }
                            if (WmsConstants.IN_STOCK_OVER_RECEIVE
                                || wg.isWeightOut() &&overRate < WmsConstants.OVER_WEIGHT_PERCENT_ALLOW
                                || havePermission(WmsConstants.SPECIAL_OVER_RECEIVE)
                                || isZhitong
                                )
                            {
                               
                                epdValidCount = batchCount;
                            }
                            else
                            {
                                
                                return enumValidInResult.不允许超收;
                            }
                        }
                        else
                        {
                          epdValidCount = epdMax;
                        }
                      
                        if (epdValidCount == 0)
                        {
                            continue;
                        }
                    } 
                    
                    if (seedsCnt > 0)
                        {
                            seedsCnt = epdValidCount;
                        }
                    svi.receive_order = epd.pur_order;
                    svi.seeds_count = seedsCnt;
                    svi.valid_count = epdValidCount;
                    svi.purch_d_id = epd.ID;
                    svi.price=epd.price;
                    svi.whType = isPass ?  (int)getWhType((enumInOrderType)eprd.orderType) :(int) enumWhType.不合格库;
                    logIn.Debug(string.Format(" to valid in : {0}  ",Util.getJson(svi) ));
                    if (isVirtualIn || isZhitong && epd.storeType == (int)enumInStoreType.直通越仓)// 
                    {
                        svi.zhitongPartion = zhitongPartion;// epd.zhitongPartion;
                        svi.validResult = !isVirtualIn ? (int)enumWhType.越仓收货区 : (int)enumWhType.虚拟库;
                        svi.whType = !isVirtualIn ? (int)enumWhType.越仓收货区 : (int)enumWhType.虚拟库;
                        if (/*i == 1 &&*/ purch_d_id == 0)
                        {
                            WmsInRequest wir = new WmsInRequest(preInNo);
                            if (wir.ID == 0)
                            {
                                // create new wmsInRequest
                                Erp_purch ep = new Erp_purch(epd.pur_order);
                                wir.preInOrder = preInNo;
                                wir.venderId = ep.vender;
                                wir.vender = ep.venderName;
                                wir.orderType = ep.orderType;
                                wir.orderTypeName = ep.order_typeName;
                                wir.operater = operId;
                                wir.state = (int)enumInStockOrderStatus.已验收;
                               
                                wir.Add();
                            }
                            else if(wir.state != (int)enumInStockOrderStatus.已验收)
                            {
                                wir.state = (int)enumInStockOrderStatus.已验收;
                                wir.Update();
                            }
                            WmsInRequestDetail wid = new WmsInRequestDetail();
                            wid.preInOrder = wir.preInOrder;
                            wid.goodsId = goodsId;
                            wid.validCount = epdValidCount;// batchCount;
                            wid.flowNo = flowNo;
                            wid.partion = zhitongPartion;
                            wid.orderNo = wir.preInOrder;
                            wid.operater = this.operId;
                            wid.state = !isVirtualIn ? (int)(int)enumInStockDetailStatus.入越仓收货区 : (int)(int)enumInStockDetailStatus.入虚拟库冲抵;
                            wid.entid = epd.entid;
                            wid.skuCode = svi.skuCode;
                            wid.skuId = svi.skuId;
                            wid.productDate = svi.product_date;
                            wid.batch = svi.batch;
                            wid.whType = svi.validResult;
                            wid.validbyAccount = svi.validby + "";
                            wid.validbyAccount1 = svi.validby1 + "";
                            wid.batch = String.IsNullOrEmpty(wid.batch) ? svi.product_date : wid.batch;
                            Erp_receiveValidDetail erd = new Erp_receiveValidDetail();
                            erd.flowNo = svi.flowNo;
                            erd.batch = svi.batch;
                            erd.goods_id = svi.goods_id;
                            erd.operater = svi.validby;// this.operId; 
                            erd.reason = svi.reason;
                            erd.seeds_count = svi.seeds_count;
                            erd.valid_count = svi.valid_count;
                            erd.productDate = svi.product_date;
                            erd.validDate = svi.save_date;
                            erd.validby = svi.validby;
                            erd.validby1 = svi.validby1;
                            erd.validResult = svi.validResult;
                            erd.whType = svi.validResult;
                            erd.wms_state = svi.wms_state;
                            erd.erp_state = svi.erp_state;
                            erd.preInOrder = String.IsNullOrEmpty(svi.preInOrder) ? "" : svi.preInOrder;
                            erd.skuId = svi.skuId;
                            erd.skuCode = svi.skuCode;
                            erd.partion = svi.zhitongPartion;
                            erd.validbyTime = erd.getDateTime();
                            erd.validbyTime1 = erd.validbyTime;
                            erd.price =svi.price;
                            erd.receive_order = svi.receive_order;
                            erd.Add();
                            wid.validId = erd.ID;
                            wid.Add();
                            if (isVirtualIn)
                            {
                                stkVirtial.count += wid.validCount;
                                stkVirtial.updateCountOut();
                            }
                            requestDetailIn(wir, wid, recommandWareHouse);
                        }
                    }
                    eprd.validCount += epdValidCount;
                    eprd.operater = operId;
                    eprd.Update();
                    ret = validIn(svi, isIsuLocations, recommandWareHouse, purch_d_id,isOnce); 
                    if (!ret)
                    {
                        scope.Dispose();
                        return enumValidInResult.失败;
                    }
                    ret = ret && eprd.Update() > 0;
                    batchCount = batchCount - epdValidCount;
                    if (batchCount <= 0)
                    {
                        break;
                    }
                      
                }
          
               
                /*
                //creat tasks/jobs 
                DataTable inPorts = this.getWmsInRequest.getInPortDetails(flowNo);
                dv = inPorts.DefaultView;
                dv.RowFilter = "jobNo is null";
                dv.Sort = "partion";
                int lastPartion = 0;
                foreach (DataRow dr in inPorts.Rows)
                {
                    WmsInUpPort port = new WmsInUpPort(dr);
                    if (lastPartion != port.partion)
                    {
                        port.jobNo = Util.getOrderNo(enumCreateOrderType.pickJobNo, _obj.getNextSeq(enumCreateOrderType.pickJobNo));
                        port.Update();
                        WmsFlow wmsflow = new WmsFlow(); 
                            wmsflow.operater = operId;
                            wmsflow.orderNo = preInNo;
                            wmsflow.flowNo = flowNo;
                            wmsflow.type = (int)enumStockRecordType.普通入库;
                            wmsflow.typeName = enumStockRecordType.普通入库.ToString(); ; 
                            wmsflow.task = port.jobNo;
                            wmsflow.taskPartion = port.partion;
                            wmsflow.Add(); 
                    } 
                    lastPartion = port.partion;  
                }
                */
                scope.Complete();
                return enumValidInResult.成功;
            }
        }
        /// 
        /// 按单取消
        /// 
        /// 预到单SkuID
        /// 
        internal bool retrieveValidByPreNo(string preInNo, int skuId = 0)
        {
            logIn.Debug("do retrieve by preInNo " + preInNo);
            WmsInRequestDetail wid = new WmsInRequestDetail();
            DataTable dt = wid.getByPreInOrder(preInNo);
            foreach (DataRow dr in dt.Rows)
            {
                wid = new WmsInRequestDetail(dr);
                if (skuId == 0 || skuId > 0 && skuId == wid.skuId)
                {
                  if(!retrieveValidByDetailId(wid.ID))
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        /// 
        /// 按板取消
        /// 
        /// 
        /// 
        internal bool retrieveValidByFlow(string flowNo)
        {
            WmsInRequestDetail wid = new WmsInRequestDetail();
            DataTable dt = wid.getByFlowNo(flowNo);
            foreach (DataRow dr in dt.Rows)
            {
                wid = new WmsInRequestDetail(dr);
                if (flowNo == wid.flowNo)
                {
                    retrieveValidByDetailId(wid.ID);
                }
            }
            return true;
        }
        /// 
        /// 撤销验收记录
        /// 
        /// 验收记录ID,wmsRequestInDetail.id
        /// 
        internal bool retrieveValidByDetailId(int detailId)
        {
            WmsInRequestDetail wid = new WmsInRequestDetail(detailId);
            WmsInRequest wmsInRequest = new WmsInRequest(wid.orderNo);
            wmsInRequest.state = (int)enumInStockOrderStatus.待验收;
            WmsInUpPort wip = new WmsInUpPort();
            DataTable dtWip = wip.getJobsByFlowSku(wid.flowNo, wid.skuId);
            DataTable dt = new Erp_receiveValidDetail().getDetailByFlowNo(wid.preInOrder, wid.flowNo);
            using (TransactionScope scope = new TransactionScope())
            {
                foreach (DataRow dr in dtWip.Rows)
                {
                    wip = new WmsInUpPort(dr);
                    if (wip.detailId == detailId)
                    {
                        if (wip.state == (int)enumInStockDetailStatus.上架完成 
                            || wip.state == (int)enumInStockDetailStatus.部分上架)
                        {
                            //continue;
                            logIn.Debug(" return false,  wip.state " + (enumInStockDetailStatus)wip.state);
                            return false;
                        }
                        WmsStock wmsStock = new WmsStock(wip.locationId, wip.skuId, wip.goodsId);
                        if (wmsStock.ID > 0)
                        {
                            wmsStock.countIn -= wip.count;
                            wmsStock.updateCountOut();
                        }
                        wip.state = (int)enumInStockDetailStatus.取消上架;
                        wip.description += String.Format("上架取消 by {0},{1}", operId, DateTime.Now);
                        wip.Update();
                    }
                }
                Erp_purch_receive_pre epr;
                Erp_receiveValidDetail erv;
                decimal leftcnt = 0;
                foreach (DataRow dr in dt.Rows)
                {
                    erv = new Erp_receiveValidDetail(dr);
                   // if (erv.skuId == wid.skuId)
                      if (erv.ID == wid.validId)
                     {
                        epr = new Erp_purch_receive_pre(erv.preInOrder, erv.purch_d_id);
                        Erp_purch_d epd = new Erp_purch_d(erv.purch_d_id);
                      
                        if(epr.validCount >= wid.validCount)
                        {
                            epr.validCount -= wid.validCount;
                            epd.validCount -= wid.validCount;
                            leftcnt = 0;
                        }
                        else
                        {  
                            leftcnt = wid.validCount - epr.validCount; 
                            epd.validCount =0; 
                            epr.validCount = 0;
                          
                        }
                        if(leftcnt > 0)
                        {
                            logIn.Error( string.Format("retrieve valid wid {0} result error: left cnt {1} " ,detailId,leftcnt));
                            return false;
                        } 
                        epr.Update(); 
                      
                        epd.wms_state = (int)enumReceiveStockDetailStatus.待验收;
                        epd.Update();
                        erv.Delete();
                    }
                }
                Erp_purch epc = new Erp_purch(wip.orderNo);
                epc.wms_state = 0;
                epc.Update();
                zhiTongSeedOutRetrieve(wid ); 
                wid.Delete();
                wmsInRequest.Update();
                scope.Complete();
            }
            return true;
        }
        private void zhiTongSeedOutRetrieve(WmsInRequestDetail wid)
        {
            if (wid.outDetailId == 0)
            {
                return;
            }
            decimal seedCnt = wid.validCount;
            string flowNo = wid.flowNo;
          
            WmsOutPickDetail wod = new WmsOutPickDetail(wid.outDetailId);  
            
            logIn.Debug(string.Format(" retrive zhitong inDetailId: {0}, seedCnt :{1}, flowNo: {2}, outDetail id: {3}", wid.ID, seedCnt, flowNo,wid.outDetailId));
            wod.seeded -= seedCnt;
           // wid.receiveCount -= seedCnt;
          
            wod.state = (int)enumOutStockDetailStatus.另单播种;           
            wod.Update();
            WmsOutPickRequest wopk = new WmsOutPickRequest(wod.pickOrderNo);
            if (wopk.state == (int)enumOutStockRequestStatus.分拣完成)
            {
                wopk.state = (int)enumOutStockRequestStatus.正在分拣;
                wopk.Update();
            } else if (wopk.state > (int)enumOutStockRequestStatus.分拣完成)
            {
                throw new Exception(wopk.pickOrderNo + "  状态" + (enumOutStockRequestStatus)wopk.state);
            }
            
            
            wid.validCount -= seedCnt;
            wid.Update();
            WmsOutPickPort wop = new WmsOutPickPort();
           DataTable dt = wop.getFlowNoDetails(wid.flowNo, wid.goodsId, wid.batch);
            foreach(DataRow dr in dt.Rows)
            {
                wop = new WmsOutPickPort(dr);
                wop.state = (int)enumPickState.已关闭;
                wop.description = "验收取消";
                wop.Update();
            }
            WmsPlateStock_tmp wps = new WmsPlateStock_tmp();
              dt = wps.getPlateStockDetail(flowNo);
            foreach (DataRow dr in dt.Rows)
            {
                wps = new WmsPlateStock_tmp(dr);
                wps.Delete();
            }
             
        }
         
   
        /// 
        /// 取消上架任务,重新验货入库
        /// 同批次的,同托盘的其他任务一起取消
        /// 
        /// up shelf job flowno
        /// up shelf job id 
        /// 
        internal bool retrieveValidByJobId(int jobId)
        {
            WmsInUpPort wip = new WmsInUpPort(jobId);
            if (wip.skuId == 0 || wip.upCount > 0)
            {
                return false;
            }
            wip.state = (int)enumInStockDetailStatus.取消上架;
            wip.description += String.Format("上架取消 by {0},{1}", operId, DateTime.Now);
            Erp_purch_receive_pre epr;
            Erp_receiveValidDetail erv;
            DataTable dt = new Erp_receiveValidDetail().getDetailByFlowNo(wip.inPreOrder, wip.flowNo);
            DataTable dtWip = wip.getJobsByFlowSku(wip.flowNo, wip.skuId);
            using (TransactionScope scope = new TransactionScope())
            {
                foreach (DataRow dr in dtWip.Rows)
                {
                    wip = new WmsInUpPort(dr);
                    if (wip.state == (int)enumInStockDetailStatus.上架完成 || wip.state == (int)enumInStockDetailStatus.部分上架)
                    {
                        continue;
                    }
                    WmsStock wmsStock = new WmsStock(wip.locationId, wip.skuId, wip.goodsId);
                    if (wmsStock.ID > 0)
                    {
                        wmsStock.countIn -= wip.count;
                        wmsStock.updateCountOut();
                    }
                }
                foreach (DataRow dr in dt.Rows)
                {
                    erv = new Erp_receiveValidDetail(dr);
                    if (erv.skuId == wip.skuId)
                    {
                        epr = new Erp_purch_receive_pre(erv.preInOrder, erv.purch_d_id);
                        epr.validCount -= wip.count;
                        epr.Update();
                        Erp_purch_d epd = new Erp_purch_d(erv.purch_d_id);
                        epd.validCount -= wip.count;
                        epd.wms_state = (int)enumReceiveStockDetailStatus.待验收;
                        epd.Update();
                        erv.Delete();
                        WmsInRequestDetail wid = new WmsInRequestDetail(erv.receive_order, erv.ID);
                        wid.Delete();
                    }
                }
                wip.retrieveJobs(wip.flowNo, wip.skuId, wip.description);
                Erp_purch epc = new Erp_purch(wip.orderNo);
                epc.wms_state = 0;
                epc.Update();
                WmsInRequest wmsInRequest = new WmsInRequest(wip.orderNo);
                wmsInRequest.state = (int)enumInStockOrderStatus.待验收;
                wmsInRequest.Update();
                scope.Complete();
            }
            return true;
        }
        internal bool isFlowNoValid(string preInOrder, string flowNo)
        {
            DataTable dt = new Erp_receiveValidDetail().getDetailByFlowNo(preInOrder, flowNo);
            return dt.Rows.Count > 0;
        }
        internal DataTable getPreValidResult4Wince(string preInNo, string flowNo, bool showAllUsers = false)
        { 
           // logIn.Debug(string.Format("取上架任务  preInNo:{0},flowNo:{1},operId{2},showAllUsers:{3}",preInNo,flowNo,operId, showAllUsers));
            if (showAllUsers)
            {
                return getWmsInRequest.getPreValidResult4Wince(preInNo, flowNo, 0);
            }
           
            return getWmsInRequest.getPreValidResult4Wince(preInNo, flowNo, operId);
        }
        internal DataTable getValidInDetail(string preInNo, string flowNo)
        {
           // logIn.Debug("to get valid in detail, preInNo is " + preInNo + ", flowNo is " + flowNo);
           DataTable dt= getWmsInRequest.getValidInDetail(preInNo.Trim(), flowNo.Trim());
           // logIn.Debug("return valid detail rows cnt " + dt.Rows.Count);
            return dt;
        }
     
        internal DataSet queryReceivesByVender(string querystr, int rownumStart, int rownumEnd)
        {
            DataSet ds = erpPurchObj.queryReceivesByVender(querystr, rownumStart, rownumEnd);
            /*
           DataView dv = ds.Tables[0].DefaultView;
           dv.Sort = "vender";
           string vender="";
           if (dv.Count > 0)
           {
               vender=dv[0]["vender"].ToString();
               dv.RowFilter =string.Format("vender ='{0}'" ,vender );
                  ds.Tables.Add(dv.ToTable("vender"));
                  DataTable dt = getReceivePreSumByVenderNotValided(vender).Copy() ;
                  dt.TableName = "venderPres";
                  ds.Tables.Add(dt);
           }
           */
            return ds;
        }
        internal DataTable getReceiveDetailByPreInOrder(string preInOrder)
        {
            return this.preInObj.getPreInDetailWindows(preInOrder);
        }
        public DataSet getPreInVendDetailsWindows(string venderPinyin, int orderType)
        {
            return this.preInObj.getPreInVendDetailsWindows(venderPinyin, orderType);
        }
        public DataTable getRequestByVenderPinyin(string pinYin, enumInStockOrderStatus status, int orderType)
        {
            return erpPurchObj.getRequestByVenderPinyin(pinYin, status, orderType);
        }
        /// 
        /// 扫描板号,返回直通物品订单明细
        /// 
        /// 
        /// 
        public DataTable getZhiTongOrderDetail(string flowNo)
        {
            return getWmsInRequest.getZhiTongOrderDetail(flowNo);
        }
        //-----------------------------------------------------test
        /// 
        /// do stock in process 
        /// 
        internal void createDataForTestOnly()
        {
            logTest.Debug(" 开始 流程 测试。。。。。。。。。。。。。》》");
            /* 
             logTest.Debug(string.Format("TEST_CREATE_PURCH_IN: {0},  TEST_VALIDIN:{1}," +
                 " TEST_ONSHELF:{2},  TEST_CREATE_SALES_OUT:{3},  TEST_PICK_OUT:{4}", WmsConstants.TEST_CREATE_PURCH_IN
                , WmsConstants.TEST_VALIDIN, WmsConstants.TEST_ONSHELF, WmsConstants.TEST_CREATE_SALES_OUT, WmsConstants.TEST_PICK_OUT));
             */
            try
            {
                string vender = "GY0014";
                Erp_bussinessDoc be = new Erp_bussinessDoc();
                lWmsOutRequest lop = new lWmsOutRequest(282);
                /*
                DataTable dt=  be.QueryActived().Tables[0];               
                int i = new Random().Next(0, dt.Rows.Count - 1);
                be = new Erp_bussinessDoc(dt.Rows[i]);
                vender = be.businessId;
                */
                DataTable dt = new Erp_purch().getCusts4InTest();
                if (dt.Rows.Count > 0)
                {
                    int i = new Random().Next(0, dt.Rows.Count - 1);
                    vender = dt.Rows[i][0].ToString();
                }
                int itemCnt = 100;
                decimal boxcnt = new Random().Next(1,2);
                decimal bulkCnt = 2;
                if (WmsConstants.TEST_CREATE_PURCH_IN)
                {
                // to create purch in .....
                    logTest.Debug(" 开始 入库收货 测试。。。。。。。。");
               
               
                    createTestIn(vender, itemCnt, boxcnt, bulkCnt, 0);
                    createZhitongTestIn(vender, itemCnt, boxcnt, bulkCnt, 0);
                }
                if (WmsConstants.TEST_VALIDIN)
                {
                    int i = 0;
                    foreach (DataRow dr in dt.Rows)
                    {
                        // int i = new Random().Next(0, dt.Rows.Count - 1);
                        // vender = dt.Rows[i][0].ToString();
                        i++;
                        if (i > WmsConstants.TEST_VALID_IN_ORDER_CNT)
                        {
                            break;
                        }
                        vender = dr[0].ToString();
                        string preNo = autoPreIn(vender);
                        string flowNo = autoValidIn(preNo);
                        if (string.IsNullOrEmpty(flowNo)){
                             autoValidInZhitong(preNo);//
                        }
                        preInDone(preNo);
                        if (WmsConstants.TEST_ONSHELF)
                        {
                            logTest.Debug(" 开始 入库上架 测试。。。。。。。。");
                            bool showAllusers = false;
                            autoOnShelf(preNo, flowNo, showAllusers);
                        }
                    } 
                  //  autoValidInZhitong();
                 
                }
                if (WmsConstants.TEST_CREATE_SALES_OUT)
                {
                    // to create sale out.....
                    logTest.Debug(" 开始 出库定位 测试。。。。。。。。");
                   
                    string custId = null;
                    lop.testCreateSales(custId);
                }
                // test pick out
                if (WmsConstants.TEST_PICK_OUT)
                {
                    logTest.Debug(" 开始 出库拣货 测试。。。。。。。。");
                   
                    lop.testPickOut();
                    autoRepOnShelf();
                }
                if (WmsConstants.TEST_PLATE_OUT)
                {
                    logTest.Debug(" 开始 容器 测试。。。。。。。。");
                    lop.inPlateTest();
                }
                if (WmsConstants.TEST_PANDIAN_PROCESS)
                {
                    logTest.Debug(" 开始 盘点 测试。。。。。。。。");
                    lWmsStockPandian lsp = new lWmsStockPandian(3335);
                    lsp.testPandian();
                }
                
            }
            catch(Exception e)
            {
                logTest.Error(e);
            }
            logTest.Debug(" 结束 流程 测试。。。。。。。。。。。。。《《");
        }
        
        /// 
        /// 测试入库
        /// 
        public bool createTestIn(string vender, int itemCnt, decimal boxcnt,decimal bulkcnt, int orderType)
        {
            erpPurchObj.pur_order = "pTest" + new Random().Next(1000000);
            erpPurchObj.orderType = orderType;
            erpPurchObj.vender = vender;
            erpPurchObj.entid = "LDJNBYXGS";
            erpPurchObj.orgid = "LDJNBYXGS";
            erpPurchObj.Add();
            ErpGoods goods = new ErpGoods();
            DataTable dt = goods.QueryActived().Tables[0];
            int i = 0;
            itemCnt = itemCnt > 0 ? itemCnt : dt.Rows.Count;
            for (int j = 0; j < itemCnt; j++)
            {
                i = new Random().Next(dt.Rows.Count - itemCnt) - j;
                i = i > 0 ? i : j;
                goods = new ErpGoods(dt.Rows[i]);
                Erp_purch_d pd = new Erp_purch_d();
                pd.entid = "LDJNBYXGS";
                pd.pur_order = erpPurchObj.pur_order;
                pd.pur_order_sn = j + 1;
                pd.goods_id = goods.goodsId;
                pd.add_date = pd.getDateTime();
              //  LogHelper.debug(this.GetType(), goods.goodsName + " bigcount is " + goods.bigCount);
                pd.count = goods.bigCount * boxcnt + bulkcnt;
                pd.Add();
            }
           
            return true;
        }
        public bool createZhitongTestIn(string vender, int itemCnt, decimal boxcnt, decimal bulkcnt, int orderType)
        {
            erpPurchObj.pur_order = "pTest" + new Random().Next(1000000);
            erpPurchObj.storeType = 1;
            erpPurchObj.orderType = orderType;
            erpPurchObj.vender = vender;
            erpPurchObj.entid = "LDJNBYXGS";
            erpPurchObj.orgid = "LDJNBYXGS";
       
            WmsGoods goods = new WmsGoods();
            DataTable dt = goods.QueryActived().Tables[0];
            DataView dv = dt.DefaultView;
            dv.RowFilter = "canZhitong=1";
            int i = 0;
            itemCnt = itemCnt > 0 ? itemCnt : dv. Count;
            foreach(DataRowView drv in dv)
            {
                i++;
            
                goods = new WmsGoods(drv.Row);
                Erp_purch_d pd = new Erp_purch_d();
                pd.entid = "LDJNBYXGS";
                pd.pur_order = erpPurchObj.pur_order;
                pd.pur_order_sn = i ;
                pd.goods_id = goods.goodsId;
                pd.add_date = pd.getDateTime();
                //  LogHelper.debug(this.GetType(), goods.goodsName + " bigcount is " + goods.bigCount);
                pd.count = goods.bigCount * boxcnt *1000 + bulkcnt;
                pd.Add();
            }
            erpPurchObj.Add();
            return true;
        }
        /// 
        /// 到货通知签到
        /// 
        /// 
        /// 
        public string autoPreIn(string vender)
        {
            DataTable dt = erpPurchObj.getAll4Valid(vender);
            List list = new List();
            foreach (DataRow dr in dt.Rows)
            {
                list.Add(Convert.ToInt32(dr["id"].ToString()));
            }
            return receiveDetailsPre(enumInOrderType.采购入库, list.ToArray(), 0, vender);
        }
        /// 
        /// 验收入库
        /// 
        /// 
        public string autoValidIn()
        {
            string[] skuKeys = { "生产日期", "到期日期", "厂家批次" };
            //string[] skuValues = { "2023-1-16", "2024-1-11", "21016" };
            Dictionary skuValues = new Dictionary();
            // skuValues.Add("生产日期", String.Format("{0}{1:D2}{2:D2}",DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day));
            // logIn.Debug(Util.getShortDateString(DateTime.Now.ToShortDateString()));
            string prddate = string.Format("{0}{1:D2}{2:D2}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
            skuValues.Add("生产日期", prddate);
            skuValues.Add("到期日期", "");
            skuValues.Add("厂家批次", "");
            logTest.Debug(" 开始自动入库验收测试...............................> ");
            DataTable dt = preInObj.getAll4ValinIn(0);
          //  logTest.Debug(" 需入库记录数量  " + dt.Rows.Count);
            Erp_purch_d pd;
            string preInNo="", goodsId, flowNo;
            decimal inCount = 0;
            flowNo = "r" + new Random().Next(10000);
           
            int i = 0;
            foreach (DataRow dr in dt.Rows)
            {
                i++;
                if(WmsConstants.TEST_VALID_IN_ITEM_CNT <= i)
                {
                    break;
                }
                preInNo = dr["preInOrderNo"].ToString();
                goodsId = dr["goodsId"].ToString();
                inCount = Convert.ToDecimal(dr["newCount4Valid"].ToString());
                try
                {
                    validIn(preInNo, flowNo, goodsId, inCount, 1, skuValues, true, true,false);
                }
                catch (Exception ex) { logTest.Error(ex); }
            }
            stackDone(preInNo, flowNo);
            logTest.Debug(" 需入库记录数量  " +i);
            logTest.Debug("自动入库验收测试.......<");
            logTest.Debug(prddate);
            return flowNo;
          
        }
        public string autoValidIn(string preOrderNo)
        {
            string[] skuKeys = { "生产日期", "到期日期", "厂家批次" };
            //string[] skuValues = { "2023-1-16", "2024-1-11", "21016" };
            Dictionary skuValues = new Dictionary();
            // skuValues.Add("生产日期", String.Format("{0}{1:D2}{2:D2}",DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day));
            // logIn.Debug(Util.getShortDateString(DateTime.Now.ToShortDateString()));
            string prddate = string.Format("{0}{1:D2}{2:D2}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
            skuValues.Add("生产日期", prddate);
            skuValues.Add("到期日期", "");
            skuValues.Add("厂家批次", "");
            logTest.Debug(" 开始自动入库验收测试...............................> ");
            DataTable dt = preInObj.getAll4ValinIn(preOrderNo,0);
            if (dt.Rows.Count == 0)
            {
                return "";
            }
            //  logTest.Debug(" 需入库记录数量  " + dt.Rows.Count);
            Erp_purch_d pd;
            string preInNo = "", goodsId, flowNo;
            decimal inCount = 0;
            flowNo = "r" + new Random().Next(10000);
            int i = 0;
            foreach (DataRow dr in dt.Rows)
            {
                i++;
                if (WmsConstants.TEST_VALID_IN_ITEM_CNT <= i)
                {
                   // break;
                }
                preInNo = dr["preInOrderNo"].ToString();
                goodsId = dr["goodsId"].ToString();
                inCount = Convert.ToDecimal(dr["newCount4Valid"].ToString());
                try
                {
                    validIn(preInNo, flowNo, goodsId, inCount, 1, skuValues, true, true, false);
                }
                catch (Exception ex) { logTest.Error(ex); }
            }
            stackDone(preInNo, flowNo);
            logTest.Debug(" 需入库记录数量  " + i);
            logTest.Debug("自动入库验收测试.......<");
            logTest.Debug(prddate);
            return flowNo;
        }
        public void autoValidInZhitong()
        {
            DataTable dt = preInObj.getAll4ValinIn(1);
            logTest.Debug(" 开始 autoValidInZhitong 。。。。。。。。rows count :" + dt.Rows .Count);
            string preInNo=null, lastPreInNo=null;
            foreach (DataRow dr in dt.Rows)
            {
              
                if (!string.IsNullOrEmpty(lastPreInNo) && preInNo==lastPreInNo)
                {
                    continue;
                }
                preInNo = dr["preInOrderNo"].ToString();
              
                autoValidInZhitong(preInNo); 
                lastPreInNo = preInNo;
               
               
            }
        }
        string autoValidInZhitong(string preNo)
        {
            if (WmsConstants.TEST_VALID_IN_ZHITONG_TAKEALL)
            {
                string[] skuKeys = { "生产日期", "到期日期", "厂家批次" };
                //string[] skuValues = { "2023-1-16", "2024-1-11", "21016" };
                Dictionary skuValues = new Dictionary();
                // skuValues.Add("生产日期", String.Format("{0}{1:D2}{2:D2}",DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day));
                // logIn.Debug(Util.getShortDateString(DateTime.Now.ToShortDateString()));
                string prddate = string.Format("{0}{1:D2}{2:D2}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
                skuValues.Add("生产日期", prddate);
                skuValues.Add("到期日期", "");
                skuValues.Add("厂家批次", "");
                logTest.Debug(" 开始自动入库直通验收测试...............................> " + preNo);
                DataTable dt = preInObj.getAll4ValinIn(preNo,  1 );
                //  logTest.Debug(" 需入库记录数量  " + dt.Rows.Count);
                Erp_purch_d pd;
                string preInNo, goodsId, flowNo;
                decimal inCount = 0;
                flowNo = "r" + new Random().Next(10000);
                int purch_d_id, outPickDetailId;
                int i = 0;
                foreach (DataRow dr in dt.Rows)
                {
                    i++;
                    if (WmsConstants.TEST_VALID_IN_ITEM_CNT <= i)
                    {
                        break;
                    }
                    preInNo = dr["preInOrderNo"].ToString();
                    goodsId = dr["goodsId"].ToString();
                    inCount = Convert.ToDecimal(dr["newCount4Valid"].ToString()); 
                    try
                    {
                        logTest.Debug("先收后分。。。。");
                        //先收后分
                        validIn(preInNo, flowNo, goodsId, inCount, 1, skuValues, true, true, false, 0, 0, true, false, true, null, 666); 
                    }
                    catch (Exception ex) { logTest.Error(ex); }
                }
                logTest.Debug(" 需入库记录数量  " + i);
                logTest.Debug("自动入库直通验收测试.......<");
                return flowNo;
            } 
            if (WmsConstants.TEST_VALID_IN_ZHITONG_TO_OUTDETAIL)
            {
                return autoValidInZhitong2(preNo);
            }
            return "";
        }
        /// 
        /// 边收边分
        /// 
        /// 
        /// 
        string autoValidInZhitong2(string preNo)
        {
            string[] skuKeys = { "生产日期", "到期日期", "厂家批次" };
            //string[] skuValues = { "2023-1-16", "2024-1-11", "21016" };
            Dictionary skuValues = new Dictionary();
            // skuValues.Add("生产日期", String.Format("{0}{1:D2}{2:D2}",DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day));
            // logIn.Debug(Util.getShortDateString(DateTime.Now.ToShortDateString()));
            string prddate = string.Format("{0}{1:D2}{2:D2}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
            skuValues.Add("生产日期", prddate);
            skuValues.Add("到期日期", "");
            skuValues.Add("厂家批次", "");
            log.Debug(" 开始自动入库直通验收...............................> " + preNo);
            DataTable dt =  new WmsInRequest().getZhiTongOrderByCust(preNo, "0");
           logTest.Debug(" 需入库记录数量  " + dt.Rows.Count);
            Erp_purch_d pd;
            string preInNo, goodsId, flowNo;
            decimal orderCnt = 0, seeded = 0, batchCnt = 0;
            flowNo = "zt" +prddate+ new Random().Next(100000);
            int purch_d_id, outPickDetailId;
            int i = 0;
            foreach (DataRow dr in dt.Rows)
            {
                i++;
             //   if (WmsConstants.TEST_VALID_IN_ITEM_CNT <= i)
                {
                  //  break;
                }
                preInNo = dr["preInOrderNo"].ToString();
                goodsId = dr["goodsId"].ToString();
                orderCnt = Convert.ToDecimal(dr["orderCount"].ToString());
                seeded = Convert.ToDecimal(dr["seeded"].ToString());
                outPickDetailId = (int)Convert.ToInt64(dr["outPickDetailId"].ToString());
                purch_d_id = (int)Convert.ToInt64(dr["id"].ToString());
                batchCnt = seeded == 0 ? orderCnt : 0;
                try
                {
                  
                        //边收边分
                       // logTest.Debug("边收边分。。。。");
                    if(batchCnt>0)
                        validIn(preInNo, flowNo, goodsId, orderCnt, 1, skuValues,true,true,false,0,0,true,false,true,null,666,outPickDetailId,purch_d_id);
                    
                    
                  
                }
                catch (Exception ex) { log.Error(ex); }
            }
           // logTest.Debug(" 需入库记录数量  " + i);
           // logTest.Debug("自动入库直通验收测试.......<");
         
            return flowNo;
        }
        /// 
        /// 上架
        /// 
        /// 
        /// 
        /// 
        /// 
        public bool autoOnShelf(string preInNo, string flowNo, bool showAllusers)
        {
            try
            {
                DataTable dt = new WmsInUpPort().getAlltasksForInTest();
                
                DataView dv = dt.DefaultView;
                dv.RowFilter = string.Format("flowNo='{0}'",flowNo) ;
                logTest.Debug(string.Format("开始 自动上架..{0}....任务数量:{1} " ,flowNo, dv.Count));
                int i = 0;
                foreach (DataRowView dr in dv)
                {
                   // if (i > WmsConstants.TEST_PICK_OUT_ITEM_CNT) break;
                    WmsInUpPort port = new WmsInUpPort(dr.Row);
                    // logTest.Debug(string.Format( "count:{0}, upcount: {1}  , to up count {2} ", port.count,port.upCount, port.count - port.upCount)  );
                    try
                    { 
                        enumRepResult rt = finishUpShelfItem(flowNo, port.ID, port.count - port.upCount, port.locationId, "");
                        i++;
                        //   logTest.Debug("上架结果 " + rt);
                    }
                    catch (Exception e)
                    {
                        logIn.Error(e);
                    } 
                } 
                logTest.Debug("结束 自动上架..  ");
            }
            catch (Exception er)
            {
                throw er;
            }
            return true;
        }
        public bool autoRepOnShelf()
        {
            try
            {
                DataTable dt = new WmsInUpPort().getAlltasksForInTest();
           
                DataView dv = dt.DefaultView;
                dv.RowFilter = "recType=" + (int)enumStockRecordType.补零入库;
                logTest.Debug(" 补零上架......任务数量: " + dv.Count);
                foreach (DataRowView dr in dv)
                { 
                    WmsInUpPort port = new WmsInUpPort(dr.Row);
                 //  logTest.Debug(string.Format( "count:{0}, upcount: {1}  , to up count {2} ", port.count,port.upCount, port.count - port.upCount)  );
                    try
                    {
                        enumRepResult rt = finishUpShelfItem(port.flowNo, port.ID, port.count - port.upCount, port.locationId, "");
                        
                          logTest.Debug("上架结果 " + rt);
                    }
                    catch (Exception e)
                    {
                        logIn.Error(e);
                    }
                }
                logTest.Debug("结束 补零上架..  ");
            }
            catch (Exception er)
            {
                throw er;
            }
            return true;
        }
                /*
                try
                {
                    DataTable dt = getPreValidResult4Wince(preInNo, flowNo, showAllusers);
                    string locationId;
                    int portId;
                    decimal count;
                    logIn.Debug("开始 自动上架......任务数量: " + dt.Rows.Count);
                    foreach (DataRow dr in dt.Rows)
                    {
                         count = Convert.ToDecimal(dr["应上数"].ToString()) - Convert.ToDecimal(dr["实上数"].ToString());
                        if (count <= 0)
                        {
                            continue;
                        }
                        portId = Convert.ToInt32(dr["portId"].ToString());
                        //WmsInUpPort port = new WmsInUpPort(portId);
                        // logIn.Debug(Util.getJson(port));
                        //   locationId =port.locationId; 
                        logIn.Debug(string.Format("port id: ({2}), 应上数 :({0}), 实上数:({1})", dr["应上数"].ToString(), dr["实上数"].ToString(), portId));
                        locationId = dr["货位"].ToString();
                        logIn.Debug(" count >0 ?" + (count > 0));
                        //count = port.count - port.upCount;
                        //logIn.Debug(string.Format( "count:{0}, upcount: {1}  , to up count {2} ", port.count,port.upCount, port.count - port.upCount)  );
                        try
                        {
                            enumRepResult rt = finishUpShelfItem(flowNo, portId, count, locationId, "");
                            logIn.Debug("上架结果 " + rt);
                        }
                        catch (Exception e) { logIn.Error(e); }
                    }
                }
                catch (Exception er)
                {
                    logIn.Debug("出错了!!! " + er.Message);
                    logIn.Error(er);
                    return false;
                }
                */
                
        
    }
}