Beispiel #1
0
        /// <summary>
        /// 入库分配
        /// </summary>
        /// <param name="inBillMaster">入库主单</param>
        /// <returns></returns>
        public bool InAllot(InBillMaster inBillMaster, Guid employeeId)
        {
            try
            {
                var inBillDetails = inBillMaster.InBillDetails.ToArray();
                var cell          = CellRepository.GetQueryable().FirstOrDefault(c => c.CellCode == inBillMaster.TargetCellCode);
                //入库单入库
                inBillMaster.InBillDetails.AsParallel().ForAll(
                    (Action <InBillDetail>) delegate(InBillDetail i)
                {
                    if (i.BillQuantity - i.AllotQuantity > 0)
                    {
                        Storage inStorage = null;
                        lock (cell)
                        {
                            inStorage = Locker.LockStorage(cell);
                            if (inStorage == null)
                            {
                                throw new Exception("锁定储位失败,储位其他人正在操作,无法分配请稍候重试!");
                            }
                            inStorage.LockTag = inBillMaster.BillNo;
                        }
                        if (inStorage.Quantity == 0 &&
                            inStorage.InFrozenQuantity == 0)
                        {
                            decimal allotQuantity = i.BillQuantity;
                            i.AllotQuantity      += allotQuantity;
                            i.RealQuantity       += allotQuantity;
                            inStorage.ProductCode = i.ProductCode;
                            inStorage.Quantity   += allotQuantity;
                            inStorage.LockTag     = string.Empty;

                            var billAllot = new InBillAllot()
                            {
                                BillNo         = inBillMaster.BillNo,
                                InBillDetailId = i.ID,
                                ProductCode    = i.ProductCode,
                                CellCode       = inStorage.CellCode,
                                StorageCode    = inStorage.StorageCode,
                                UnitCode       = i.UnitCode,
                                AllotQuantity  = allotQuantity,
                                RealQuantity   = allotQuantity,
                                Status         = "2"
                            };

                            lock (inBillMaster.InBillAllots)
                            {
                                inBillMaster.InBillAllots.Add(billAllot);
                            }
                        }
                        else
                        {
                            throw new Exception("储位数量不等于0,无法分配请稍候重试!");
                        }
                    }
                });
                //入库结单
                inBillMaster.Status         = "6";
                inBillMaster.VerifyDate     = DateTime.Now;
                inBillMaster.VerifyPersonID = employeeId;
                inBillMaster.UpdateTime     = DateTime.Now;
                InBillMasterRepository.SaveChanges();
                return(true);
            }
            catch (AggregateException ex)
            {
                resultStr = "审核失败,详情:" + ex.InnerExceptions.Select(i => i.Message).Aggregate((m, n) => m + n);
                return(false);
            }
        }
Beispiel #2
0
        public DataSet Insert()
        {
            IQueryable <InBillMaster> inBillMaster = InBillMasterRepository.GetQueryable();
            IQueryable <InBillAllot>  inBillAllot  = InBillAllotRepository.GetQueryable();
            IQueryable <InBillDetail> inBillDetail = InBillDetailRepository.GetQueryable();
            var inBillMasterQuery = inBillMaster.Where(i => i.Status == "6").Select(i => new
            {
                STORE_BILL_ID        = i.BillNo,
                RELATE_BUSI_BILL_NUM = inBillAllot.Count(a => a.BillNo == i.BillNo),
                DIST_CTR_CODE        = i.WarehouseCode,
                QUANTITY_SUM         = inBillAllot.Where(a => a.BillNo == i.BillNo).Sum(a => a.AllotQuantity / 200),
                AMOUNT_SUM           = inBillDetail.Where(d => d.BillNo == i.BillNo).Sum(d => d.Price * d.AllotQuantity / 200),
                DETAIL_NUM           = inBillDetail.Count(d => d.BillNo == i.BillNo),
                personCode           = i.VerifyPerson,
                personDate           = i.VerifyDate,
                operater             = i.OperatePerson,
                operateDate          = i.BillDate,
                BILL_TYPE            = i.BillTypeCode
            });
            DataSet ds      = this.GenerateEmptyTables();
            DataRow inbrddr = ds.Tables["WMS_IN_BILLMASTER"].NewRow();

            foreach (var p in inBillMasterQuery)
            {
                inbrddr["STORE_BILL_ID"]        = p.STORE_BILL_ID;
                inbrddr["RELATE_BUSI_BILL_NUM"] = p.RELATE_BUSI_BILL_NUM;
                inbrddr["DIST_CTR_CODE"]        = p.DIST_CTR_CODE;
                inbrddr["AREA_TYPE"]            = "0901";
                inbrddr["QUANTITY_SUM"]         = p.QUANTITY_SUM;
                inbrddr["AMOUNT_SUM"]           = p.AMOUNT_SUM;
                inbrddr["DETAIL_NUM"]           = p.DETAIL_NUM;
                inbrddr["CREATOR_CODE"]         = p.operater.ToString() ?? "";
                inbrddr["CREATE_DATE"]          = p.operateDate;
                inbrddr["AUDITOR_CODE"]         = p.personCode.ToString() ?? "";
                inbrddr["AUDIT_DATE"]           = p.personDate;
                inbrddr["ASSIGNER_CODE"]        = p.operater;
                inbrddr["ASSIGN_DATE"]          = p.operateDate;
                inbrddr["AFFIRM_CODE"]          = p.operater;
                inbrddr["AFFIRM_DATE"]          = p.operateDate;
                inbrddr["IN_OUT_TYPE"]          = "1202";
                inbrddr["BILL_TYPE"]            = p.BILL_TYPE;
                inbrddr["BILL_STATUS"]          = "99";
                inbrddr["DISUSE_STATUS"]        = "0";
                inbrddr["IS_IMPORT"]            = "1";
                ds.Tables["WMS_IN_BILLMASTER"].Rows.Add(inbrddr);
            }
            DataRow inbrddrDetail     = ds.Tables["WMS_IN_BILLDETAIL"].NewRow();
            var     inBillDetailQuery = inBillDetail.Where(i => i.InBillMaster.Status == "6").Select(i => new
            {
                STORE_BILL_DETAIL_ID = i.ID,
                STORE_BILL_ID        = i.BillNo,
                BRAND_CODE           = i.ProductCode,
                BRAND_NAME           = i.Product.ProductName,
                QUANTITY             = i.BillQuantity / 200
            });

            foreach (var p in inBillDetailQuery)
            {
                inbrddrDetail["STORE_BILL_DETAIL_ID"] = p.STORE_BILL_DETAIL_ID;
                inbrddrDetail["STORE_BILL_ID"]        = p.STORE_BILL_ID;
                inbrddrDetail["BRAND_CODE"]           = p.BRAND_CODE;
                inbrddrDetail["BRAND_NAME"]           = p.BRAND_NAME;
                inbrddrDetail["QUANTITY"]             = p.QUANTITY;
                inbrddrDetail["IS_IMPORT"]            = "0";
                ds.Tables["WMS_IN_BILLDETAIL"].Rows.Add(inbrddrDetail);
            }
            DataRow inbrddrAllot     = ds.Tables["WMS_IN_BILLALLOT"].NewRow();
            var     inBillAllotQuery = inBillAllot.Where(i => i.InBillMaster.Status == "6").Select(i => new
            {
                BUSI_ACT_ID         = i.ID,
                BUSI_BILL_DETAIL_ID = i.InBillDetailId,
                BUSI_BILL_ID        = i.BillNo,
                BRAND_CODE          = i.ProductCode,
                BRAND_NAME          = i.Product.ProductName,
                QUANTITY            = i.AllotQuantity / 200,
                DIST_CTR_CODE       = i.InBillMaster.WarehouseCode,
                STORE_PLACE_CODE    = i.Storage.CellCode,
                UPDATE_CODE         = i.Operator,
                BILL_TYPE           = i.InBillMaster.BillTypeCode
                                      //BEGIN_STOCK_QUANTITY = StorageRepository.GetQueryable().Where(s => s.ProductCode == i.ProductCode).Sum(s => s.Quantity / 200) + i.AllotQuantity,
                                      //END_STOCK_QUANTITY = i.AllotQuantity,
            });

            foreach (var p in inBillAllotQuery)
            {
                inbrddrAllot["BUSI_ACT_ID"]          = p.BUSI_ACT_ID;
                inbrddrAllot["BUSI_BILL_DETAIL_ID"]  = p.BUSI_BILL_DETAIL_ID;
                inbrddrAllot["BUSI_BILL_ID"]         = p.BUSI_BILL_ID;
                inbrddrAllot["BRAND_CODE"]           = p.BRAND_CODE;
                inbrddrAllot["BRAND_NAME"]           = p.BRAND_NAME;
                inbrddrAllot["QUANTITY"]             = p.QUANTITY;
                inbrddrAllot["DIST_CTR_CODE"]        = p.DIST_CTR_CODE;
                inbrddrAllot["ORG_CODE"]             = "01";
                inbrddrAllot["STORE_ROOM_CODE"]      = "001";
                inbrddrAllot["STORE_PLACE_CODE"]     = p.STORE_PLACE_CODE;
                inbrddrAllot["TARGET_NAME"]          = p.STORE_PLACE_CODE;
                inbrddrAllot["IN_OUT_TYPE"]          = "1202";
                inbrddrAllot["BILL_TYPE"]            = p.BILL_TYPE;
                inbrddrAllot["BEGIN_STOCK_QUANTITY"] = 0;
                inbrddrAllot["END_STOCK_QUANTITY"]   = 0;
                inbrddrAllot["DISUSE_STATUS"]        = "0";
                inbrddrAllot["RECKON_STATUS"]        = "1";
                inbrddrAllot["RECKON_DATE"]          = DateTime.Now.ToString("yyyy-MM-dd");
                inbrddrAllot["UPDATE_CODE"]          = p.UPDATE_CODE;
                inbrddrAllot["UPDATE_DATE"]          = DateTime.Now.ToString("yyyy-MM-dd");
                inbrddrAllot["IS_IMPORT"]            = "0";
                ds.Tables["WMS_IN_BILLALLOT"].Rows.Add(inbrddrAllot);
            }
            return(ds);
        }
Beispiel #3
0
        public bool AllotEdit(string billNo, long id, string cellCode, int allotQuantity, out string strResult)
        {
            bool result = false;
            var  ibm    = InBillMasterRepository.GetQueryable().FirstOrDefault(i => i.BillNo == billNo && i.Status == "3");
            var  cell   = CellRepository.GetQueryable().Single(c => c.CellCode == cellCode);

            if (ibm != null)
            {
                if (string.IsNullOrEmpty(ibm.LockTag))
                {
                    var allotDetail = ibm.InBillAllots.Single(a => a.ID == (int)id);
                    if (string.IsNullOrEmpty(allotDetail.Storage.LockTag))
                    {
                        Storage storage;
                        if (allotDetail.CellCode == cellCode)
                        {
                            storage = allotDetail.Storage;
                        }
                        else
                        {
                            storage = Locker.LockEmpty(cell);
                            if (storage != null && (storage.Quantity != 0 || storage.InFrozenQuantity != 0))
                            {
                                storage.LockTag = string.Empty;
                                StorageRepository.SaveChanges();
                                storage = null;
                            }
                        }
                        if (storage != null)
                        {
                            decimal q1 = allotDetail.InBillDetail.BillQuantity - allotDetail.InBillDetail.AllotQuantity;
                            decimal q2 = allotQuantity * allotDetail.Unit.Count;
                            if (q1 >= q2)
                            {
                                try
                                {
                                    allotDetail.InBillDetail.AllotQuantity -= allotDetail.AllotQuantity;
                                    allotDetail.Storage.InFrozenQuantity   -= allotDetail.AllotQuantity;
                                    allotDetail.InBillDetail.AllotQuantity += q2;
                                    storage.ProductCode       = allotDetail.ProductCode;
                                    storage.InFrozenQuantity += q2;
                                    storage.LockTag           = string.Empty;
                                    allotDetail.CellCode      = storage.Cell.CellCode;
                                    allotDetail.StorageCode   = storage.StorageCode;
                                    allotDetail.AllotQuantity = q2;
                                    InBillAllotRepository.SaveChanges();
                                    strResult = "保存修改成功!";
                                    result    = true;
                                }
                                catch (Exception)
                                {
                                    strResult = "保存修改失败,订单或储位其他人正在操作!";
                                }
                            }
                            else
                            {
                                strResult = "分配数量超过订单数量!";
                            }
                        }
                        else
                        {
                            strResult = "当前选择的储位不可用,其他人正在操作或已有库存!";
                        }
                    }
                    else
                    {
                        strResult = "当前储位其他人正在操作,请稍候重试!";
                    }
                }
                else
                {
                    strResult = "当前订单其他人正在操作,请稍候重试!";
                }
            }
            else
            {
                strResult = "当前订单状态不是已分配,或当前订单不存在!";
            }
            return(result);
        }
Beispiel #4
0
        public bool AllotCancel(string billNo, out string strResult)
        {
            Locker.LockKey = billNo;
            bool result = false;
            var  ibm    = InBillMasterRepository.GetQueryable()
                          .FirstOrDefault(i => i.BillNo == billNo &&
                                          i.Status == "3");

            if (ibm != null)
            {
                if (string.IsNullOrEmpty(ibm.LockTag))
                {
                    try
                    {
                        using (var scope = new TransactionScope())
                        {
                            var inAllot = InBillAllotRepository.GetQueryable()
                                          .Where(o => o.BillNo == ibm.BillNo)
                                          .ToArray();

                            var storages = inAllot.Select(i => i.Storage).ToArray();

                            if (!Locker.Lock(storages))
                            {
                                strResult = "锁定储位失败,储位其他人正在操作,无法取消分配请稍候重试!";
                                return(false);
                            }

                            inAllot.AsParallel().ForAll(
                                (Action <InBillAllot>) delegate(InBillAllot i)
                            {
                                if (i.Storage.ProductCode == i.ProductCode &&
                                    i.Storage.InFrozenQuantity >= i.AllotQuantity)
                                {
                                    lock (i.InBillDetail)
                                    {
                                        i.InBillDetail.AllotQuantity -= i.AllotQuantity;
                                    }
                                    i.Storage.InFrozenQuantity -= i.AllotQuantity;
                                    i.Storage.LockTag           = string.Empty;
                                }
                                else
                                {
                                    throw new Exception("储位的卷烟或入库冻结量与当前分配不符,信息可能被异常修改,不能取消当前入库分配!");
                                }
                            }
                                );

                            InBillAllotRepository.SaveChanges();

                            InBillAllotRepository.GetObjectSet()
                            .DeleteEntity(i => i.BillNo == ibm.BillNo);
                            //InBillAllotRepository.GetObjectQuery()
                            //    .DeleteAll(i => i.BillNo == ibm.BillNo,null);

                            ibm.Status     = "2";
                            ibm.UpdateTime = DateTime.Now;
                            InBillMasterRepository.SaveChanges();
                            result    = true;
                            strResult = "取消分配成功!";

                            scope.Complete();
                        }
                    }
                    catch (Exception e)
                    {
                        strResult = "取消分配失败,详情:" + e.Message;
                    }
                }
                else
                {
                    strResult = "当前订单其他人正在操作,请稍候重试!";
                }
            }
            else
            {
                strResult = "当前订单状态不是已分配,或当前订单不存在!";
            }
            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// 手工分配入库单
        /// </summary>
        /// <param name="billNo"></param>
        /// <param name="id"></param>
        /// <param name="cellCode"></param>
        /// <param name="allotQuantity"></param>
        /// <param name="strResult"></param>
        /// <returns></returns>
        public bool AllotAdd(string billNo, long id, string cellCode, int allotQuantity, out string strResult)
        {
            bool result = false;
            var  ibm    = InBillMasterRepository.GetQueryable().FirstOrDefault(i => i.BillNo == billNo);
            var  cell   = CellRepository.GetQueryable().Single(c => c.CellCode == cellCode);
            var  ibd    = InBillDetailRepository.GetQueryable().FirstOrDefault(i => i.ID == id);

            if (ibm != null)
            {
                if (string.IsNullOrEmpty(ibm.LockTag))
                {
                    Storage storage = Locker.LockStorage(cell);
                    if (storage != null)
                    {
                        if (allotQuantity > 0)
                        {
                            InBillAllot billAllot = null;
                            decimal     q1        = ibd.BillQuantity - ibd.AllotQuantity;
                            decimal     q2        = allotQuantity * ibd.Unit.Count;
                            if (q2 <= q1 && q2 <= (cell.MaxQuantity * ibd.Unit.Count - (storage.Quantity + storage.InFrozenQuantity)))
                            {
                                try
                                {
                                    billAllot = new InBillAllot()
                                    {
                                        BillNo         = billNo,
                                        InBillDetailId = ibd.ID,
                                        ProductCode    = ibd.ProductCode,
                                        CellCode       = storage.CellCode,
                                        StorageCode    = storage.StorageCode,
                                        UnitCode       = ibd.UnitCode,
                                        AllotQuantity  = q2,
                                        RealQuantity   = 0,
                                        Status         = "0"
                                    };
                                    ibd.AllotQuantity        += q2;
                                    storage.InFrozenQuantity += q2;
                                    storage.ProductCode       = ibd.ProductCode;
                                    ibm.InBillAllots.Add(billAllot);
                                    ibm.Status      = "3";
                                    storage.LockTag = string.Empty;
                                    StorageRepository.SaveChanges();
                                    strResult = "手工分配成功!";
                                    result    = true;
                                }
                                catch (Exception)
                                {
                                    strResult = "保存添加失败,订单或储位其他人正在操作!";
                                }
                            }
                            else
                            {
                                strResult = "分配数量超过订单数量,或者大于储位的最大数量!";
                            }
                        }
                        else
                        {
                            strResult = "分配数量必须大于0!";
                        }
                    }
                    else
                    {
                        strResult = "当前选择的储位不可用,或者分配数量超过最大托盘数,其他人正在操作!";
                    }
                }
                else
                {
                    strResult = "当前订单其他人正在操作,请稍候重试!";
                }
            }
            else
            {
                strResult = "当前订单状态不是已分配,或当前订单不存在!";
            }
            return(result);
        }
        public bool AllotAdd(string billNo, long id, string cellCode, string productname, out string strResult, out decimal allotQuantity)
        {
            bool    result   = false;
            decimal quantity = 0;

            allotQuantity = 0;
            var ibm          = InBillMasterRepository.GetQueryable().FirstOrDefault(i => i.BillNo == billNo);
            var cell         = CellRepository.GetQueryable().Single(c => c.CellCode == cellCode);
            var cell0        = CellRepository.GetQueryable();
            var storages0    = StorageRepository.GetQueryable();
            var cellstorage  = cell0.Join(storages0, c => c.CellCode, s => s.CellCode, (c, s) => new { cell0 = c, storages0 = s });
            var cellstorages = cellstorage.Where(c => c.cell0.CellCode == cellCode).Select(c => new { product = c.storages0.Product.ProductName }).ToArray();
            var storages     = StorageRepository.GetQueryable().FirstOrDefault(s => s.CellCode == cellCode);

            if (storages != null)
            {
                quantity = storages.Quantity;
            }
            var ibd = InBillDetailRepository.GetQueryable().FirstOrDefault(i => i.ID == id);

            if (ibm != null)
            {
                if (string.IsNullOrEmpty(ibm.LockTag))
                {
                    Storage storage = Locker.LockStorage(cell);
                    if (storage != null)
                    {
                        if (productname == cellstorages[0].product || quantity == 0)
                        {
                            decimal q2 = ibd.BillQuantity - ibd.AllotQuantity;
                            if (q2 > 0)
                            {
                                InBillAllot billAllot = null;
                                decimal     q1        = (cell.MaxQuantity >= ibd.Product.CellMaxProductQuantity ? ibd.Product.CellMaxProductQuantity : cell.MaxQuantity) * ibd.Product.Unit.Count - (storage.Quantity + storage.InFrozenQuantity);
                                if (q2 <= q1)
                                {
                                    try
                                    {
                                        billAllot = new InBillAllot()
                                        {
                                            BillNo         = billNo,
                                            InBillDetailId = ibd.ID,
                                            ProductCode    = ibd.ProductCode,
                                            CellCode       = storage.CellCode,
                                            StorageCode    = storage.StorageCode,
                                            UnitCode       = ibd.UnitCode,
                                            AllotQuantity  = q2,
                                            RealQuantity   = 0,
                                            Status         = "0"
                                        };
                                        allotQuantity             = q2 / ibd.Unit.Count;
                                        ibd.AllotQuantity        += q2;
                                        storage.InFrozenQuantity += q2;
                                        storage.ProductCode       = ibd.ProductCode;
                                        ibm.InBillAllots.Add(billAllot);
                                        ibm.Status      = "3";
                                        storage.LockTag = string.Empty;
                                        StorageRepository.SaveChanges();
                                        strResult = "";
                                        result    = true;
                                    }
                                    catch (Exception)
                                    {
                                        strResult     = "保存添加失败,订单或储位其他人正在操作!";
                                        allotQuantity = 0;
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        billAllot = new InBillAllot()
                                        {
                                            BillNo         = billNo,
                                            InBillDetailId = ibd.ID,
                                            ProductCode    = ibd.ProductCode,
                                            CellCode       = storage.CellCode,
                                            StorageCode    = storage.StorageCode,
                                            UnitCode       = ibd.UnitCode,
                                            AllotQuantity  = q1,
                                            RealQuantity   = 0,
                                            Status         = "0"
                                        };
                                        allotQuantity             = q1 / ibd.Unit.Count;
                                        ibd.AllotQuantity        += q1;
                                        storage.InFrozenQuantity += q1;
                                        storage.ProductCode       = ibd.ProductCode;
                                        ibm.InBillAllots.Add(billAllot);
                                        ibm.Status      = "3";
                                        storage.LockTag = string.Empty;
                                        StorageRepository.SaveChanges();
                                        strResult = "";
                                        result    = true;
                                    }
                                    catch (Exception)
                                    {
                                        strResult = "保存添加失败,订单或储位其他人正在操作!";
                                    }
                                }
                            }
                            else
                            {
                                strResult = "分配数量必须大于0!";
                            }
                        }
                        else
                        {
                            strResult = "该货位已存在其他产品,不能放入该产品!";
                        }
                    }
                    else
                    {
                        strResult = "当前选择的储位不可用,或者分配数量超过最大托盘数,其他人正在操作!";
                    }
                }
                else
                {
                    strResult = "当前订单其他人正在操作,请稍候重试!";
                }
            }
            else
            {
                strResult = "当前订单状态不是已分配,或当前订单不存在!";
            }
            return(result);
        }
        public void Allot(string connectionId, ProgressState ps, CancellationToken cancellationToken, string billNo, string[] areaCodes)
        {
            Locker.LockKey = billNo;
            ConnectionId   = connectionId;
            ps.State       = StateType.Start;
            ps.Messages.Add("开始分配!");
            NotifyConnection(ps.Clone());
            IQueryable <THOK.Authority.DbModel.SystemParameter> systemParQuery = SystemParameterRepository.GetQueryable();
            IQueryable <InBillMaster> inBillMasterQuery = InBillMasterRepository.GetQueryable();
            IQueryable <Cell>         cellQuery         = CellRepository.GetObjectSet()
                                                          .Include("Warehouse").Include("Area").Include("Storages");

            InBillMaster billMaster = inBillMasterQuery.Single(b => b.BillNo == billNo);

            if (!CheckAndLock(billMaster, ps))
            {
                return;
            }

            var isDefaultProduct  = systemParQuery.FirstOrDefault(s => s.ParameterName == "IsDefaultProduct");  //查询预设的卷烟其他卷烟是否可入 0 否 1是
            var InMantissaIsPiece = systemParQuery.FirstOrDefault(s => s.ParameterName == "InMantissaIsPiece"); //查询入库的尾数是否放入件烟区  0 否 1是

            //选择未分配的细单数组;
            var billDetails = billMaster.InBillDetails
                              .Where(b => (b.BillQuantity - b.AllotQuantity) > 0)
                              .ToArray();


            //选择当前订单操作目标仓库;
            var cells = cellQuery.Where(c => c.WarehouseCode == billMaster.WarehouseCode &&
                                        c.Warehouse.IsActive == "1" &&
                                        c.Area.IsActive == "1" &&
                                        c.IsActive == "1" &&
                                        (areaCodes.Any(a => a == c.AreaCode) ||
                                         (!areaCodes.Any() && c.Area.AllotInOrder > 0)))
                        .ToArray();

            //1:主库区;2:件烟区;
            //3;条烟区;4:暂存区;
            //5:备货区;6:残烟区;
            //7:罚烟区;8:虚拟区;
            //9:其他区;

            //排除 件烟区,条烟区 货位是单一存储的空货位;
            string [] areaTypes = new string [] { "2", "3" };
            var       cells1    = cells.Where(c => c.Area.AreaType != "2" && c.Area.AreaType != "3"
                                              //areaTypes.All(a => a != c.Area.AreaType)
                                              && c.IsSingle == "1" &&
                                              (c.Storages.Count == 0 ||
                                               c.Storages.Any(s => string.IsNullOrEmpty(s.LockTag) &&
                                                              s.Quantity == 0 &&
                                                              s.InFrozenQuantity == 0)));

            //条烟区 货位是单一存储的货位(不必是空货位,因为条烟会多次存储到同一个货位);
            areaTypes = new string[] { "3" };
            var cell2 = cells.Where(c => areaTypes.Any(a => a == c.Area.AreaType) &&
                                    c.IsSingle == "1");

            //件烟区 货位是单一存储的空货位;
            areaTypes = new string[] { "2", "4" };
            var cell3 = cells.Where(c => areaTypes.Any(a => a == c.Area.AreaType) &&
                                    c.IsSingle == "1" &&
                                    c.Storages.Any(s => string.IsNullOrEmpty(s.LockTag) &&
                                                   s.Product != null &&
                                                   (s.Quantity > 0 || s.InFrozenQuantity > 0) &&
                                                   (c.MaxQuantity >= s.Product.CellMaxProductQuantity ? s.Product.CellMaxProductQuantity : c.MaxQuantity) * s.Product.Unit.Count > s.Quantity + s.InFrozenQuantity));

            //件烟区 货位是单一存储的空货位;
            areaTypes = new string[] { "2" };
            var cell4 = cells.Where(c => areaTypes.Any(a => a == c.Area.AreaType) &&
                                    c.IsSingle == "1" &&
                                    (c.Storages.Count == 0 ||
                                     c.Storages.Any(s => string.IsNullOrEmpty(s.LockTag) &&
                                                    s.Quantity == 0 &&
                                                    s.InFrozenQuantity == 0
                                                    )
                                    )
                                    );

            //非货位管理区
            var cell5 = cells.Where(c => c.IsSingle == "0");


            //排除 件烟区,条烟区
            var cellQueryFromList1 = cells1.Where(c => c.Storages.Count == 0 ||
                                                  c.Storages.Any(s => string.IsNullOrEmpty(s.LockTag) &&
                                                                 s.Quantity == 0 &&
                                                                 s.InFrozenQuantity == 0))
                                     .OrderBy(c => c.Area.AllotInOrder);
            //条烟区
            var cellQueryFromList2 = cell2.OrderBy(c => c.Area.AllotInOrder);

            //件烟区 --入库尾数可以放入件烟区
            var cellQueryFromList3 = cell3.OrderBy(c => c.Area.AllotInOrder);

            if (InMantissaIsPiece.ParameterValue != "0")
            {
                cellQueryFromList3 = cell3.Where(c => c.Storages.Any(s => (c.MaxQuantity >= s.Product.CellMaxProductQuantity ? s.Product.CellMaxProductQuantity : c.MaxQuantity) * s.Product.Unit.Count > s.Quantity + s.InFrozenQuantity))
                                     .OrderBy(c => c.Area.AllotInOrder);
            }
            //件烟区 --入库尾数不放入件烟区
            var cellQueryFromList4 = cell4.Where(c => c.Storages.Count == 0 ||
                                                 c.Storages.Any(s => string.IsNullOrEmpty(s.LockTag) &&
                                                                s.Quantity == 0 &&
                                                                s.InFrozenQuantity == 0))
                                     .OrderBy(c => c.Area.AllotInOrder);

            //非货位管理区
            var cellQueryFromList5 = cell5.OrderBy(c => c.Area.AllotInOrder % 10000);

            foreach (var billDetail in billDetails)
            {
                //分配预设当前卷烟的货位;
                var cs = cellQueryFromList1.Where(c => c.DefaultProductCode == billDetail.ProductCode);
                AllotPallet(billMaster, billDetail, cs, cancellationToken, ps);

                //分配没预设卷烟的货位;
                cs = cellQueryFromList1.Where(c => string.IsNullOrEmpty(c.DefaultProductCode) &&
                                              (string.IsNullOrEmpty(billDetail.Product.PointAreaCodes) || billDetail.Product.PointAreaCodes.Contains(c.AreaCode)));
                AllotPallet(billMaster, billDetail, cs, cancellationToken, ps);

                if (isDefaultProduct.ParameterValue != "0")//判断预设卷烟后不能放入其他烟
                {
                    //分配预设其他卷烟的货位;
                    cs = cellQueryFromList1.Where(c => c.DefaultProductCode != billDetail.ProductCode &&
                                                  !string.IsNullOrEmpty(c.DefaultProductCode) &&
                                                  (string.IsNullOrEmpty(billDetail.Product.PointAreaCodes) || billDetail.Product.PointAreaCodes.Contains(c.AreaCode)));
                    AllotPallet(billMaster, billDetail, cs, cancellationToken, ps);
                }

                //分配条烟到条烟区;
                cs = cellQueryFromList2.Where(c => c.DefaultProductCode == billDetail.ProductCode ||
                                              (c.Storages.Count == 1 &&
                                               c.Storages.First().ProductCode == billDetail.ProductCode)
                                              );
                AllotBar(billMaster, billDetail, cs, cancellationToken, ps);
                //分配条烟到条烟区;
                if (!cs.Any())
                {
                    cs = cellQueryFromList2.Where(c => (isDefaultProduct.ParameterValue == "0" ? string.IsNullOrEmpty(c.DefaultProductCode) : true));
                    AllotBar(billMaster, billDetail, cs, cancellationToken, ps);
                }

                //分配未满一托盘的卷烟到件烟区;
                cs = cellQueryFromList3.Where(c => (isDefaultProduct.ParameterValue == "0" ? string.IsNullOrEmpty(c.DefaultProductCode) : true) || c.DefaultProductCode == billDetail.ProductCode);
                if (cellQueryFromList2.Any())
                {
                    if (InMantissaIsPiece.ParameterValue != "0")
                    {
                        AllotPiece(billMaster, billDetail, cs, cancellationToken, ps);
                    }
                    cs = cellQueryFromList4.Where(c => (isDefaultProduct.ParameterValue == "0" ? string.IsNullOrEmpty(c.DefaultProductCode) : true));
                    AllotPiece(billMaster, billDetail, cs, cancellationToken, ps);
                }
                else
                {
                    if (InMantissaIsPiece.ParameterValue != "0")
                    {
                        AllotPieceAndBar(billMaster, billDetail, cs, cancellationToken, ps);
                    }
                    cs = cellQueryFromList4.Where(c => (isDefaultProduct.ParameterValue == "0" ? string.IsNullOrEmpty(c.DefaultProductCode) : true));
                    AllotPieceAndBar(billMaster, billDetail, cs, cancellationToken, ps);
                }

                //分配未满一托盘的卷烟到下层货架;
                cs = cellQueryFromList1.Where(c => c.Layer == 1 && (isDefaultProduct.ParameterValue == "0" ? string.IsNullOrEmpty(c.DefaultProductCode) : true) &&
                                              (string.IsNullOrEmpty(billDetail.Product.PointAreaCodes) || billDetail.Product.PointAreaCodes.Contains(c.AreaCode)));
                if (cellQueryFromList2.Count() > 0)
                {
                    AllotPiece(billMaster, billDetail, cs, cancellationToken, ps);
                }
                else
                {
                    AllotPieceAndBar(billMaster, billDetail, cs, cancellationToken, ps);
                }

                //分配未分配卷烟到其他库区;
                cs = cellQueryFromList1.Where(c => (isDefaultProduct.ParameterValue == "0" ? string.IsNullOrEmpty(c.DefaultProductCode) : true) &&
                                              (string.IsNullOrEmpty(billDetail.Product.PointAreaCodes) || billDetail.Product.PointAreaCodes.Contains(c.AreaCode)));
                AllotPiece(billMaster, billDetail, cs, cancellationToken, ps);

                //分配未分配卷烟到其他非货位管理货位;
                while (!cancellationToken.IsCancellationRequested && (billDetail.BillQuantity - billDetail.AllotQuantity) > 0)
                {
                    var c = cellQueryFromList5.Where(i => !i.Storages.Any() ||
                                                     i.Storages.Count() < i.MaxPalletQuantity ||
                                                     i.Storages.Any(s => string.IsNullOrEmpty(s.LockTag) &&
                                                                    s.Quantity == 0 &&
                                                                    s.InFrozenQuantity == 0))
                            .Where(i => string.IsNullOrEmpty(billDetail.Product.PointAreaCodes) || billDetail.Product.PointAreaCodes.Contains(i.AreaCode))
                            .FirstOrDefault();

                    if (c != null)
                    {
                        lock (c)
                        {
                            decimal allotQuantity = (c.MaxQuantity >= billDetail.Product.CellMaxProductQuantity ? billDetail.Product.CellMaxProductQuantity : c.MaxQuantity) * billDetail.Product.Unit.Count;
                            decimal billQuantity  = billDetail.BillQuantity - billDetail.AllotQuantity;
                            allotQuantity = allotQuantity < billQuantity ? allotQuantity : billQuantity;
                            var targetStorage = Locker.LockStorage(c);
                            if (targetStorage != null &&
                                targetStorage.Quantity == 0 &&
                                targetStorage.InFrozenQuantity == 0)
                            {
                                Allot(billMaster, billDetail, c, targetStorage, allotQuantity, ps);
                                Locker.UnLockStorage(targetStorage);
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            string billno = billMaster.BillNo;

            if (billMaster.InBillDetails.Any(i => i.BillQuantity - i.AllotQuantity > 0))
            {
                ps.State = StateType.Warning;
                ps.Errors.Add("分配未全部完成,没有储位可分配!");
                NotifyConnection(ps.Clone());

                InBillMasterRepository.GetObjectSet()
                .UpdateEntity(i => i.BillNo == billno,
                              i => new InBillMaster()
                {
                    LockTag = ""
                });
            }
            else
            {
                ps.State = StateType.Info;
                ps.Messages.Add("分配完成,开始保存请稍候!");
                NotifyConnection(ps.Clone());

                billMaster.Status = "3";
                try
                {
                    if (!cancellationToken.IsCancellationRequested)
                    {
                        billMaster.LockTag = string.Empty;
                        CellRepository.SaveChanges();
                        ps.State = StateType.Info;
                        ps.Messages.Clear();
                        ps.Messages.Add("分配成功!");
                        NotifyConnection(ps.Clone());
                    }
                }
                catch (Exception e)
                {
                    ps.State = StateType.Error;
                    ps.Messages.Add("保存失败,详情:" + e.Message);
                    NotifyConnection(ps.Clone());
                }
                finally
                {
                    InBillMasterRepository.GetObjectSet()
                    .UpdateEntity(i => i.BillNo == billno,
                                  i => new InBillMaster()
                    {
                        LockTag = ""
                    });
                }
            }
        }