コード例 #1
0
        public void Allot(string connectionId, Model.ProgressState ps, System.Threading.CancellationToken cancellationToken, string billNo, string[] areaCodes)
        {
            Locker.LockKey = billNo;
            ConnectionId   = connectionId;
            ps.State       = StateType.Start;
            NotifyConnection(ps.Clone());

            IQueryable <OutBillMaster> outBillMasterQuery = OutBillMasterRepository.GetQueryable();
            IQueryable <Cell>          cellQuery          = CellRepository.GetQueryable();
            IQueryable <Storage>       storageQuery       = StorageRepository.GetQueryable();

            OutBillMaster billMaster = outBillMasterQuery.Single(b => b.BillNo == billNo);

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

            //选择未分配的细单;
            var billDetails = billMaster.OutBillDetails.Where(b => (b.BillQuantity - b.AllotQuantity) > 0).ToArray();
            //选择当前订单操作目标仓库;
            var storages = storageQuery.Where(s => s.Cell.WarehouseCode == billMaster.WarehouseCode);

            if (areaCodes.Length > 0)
            {
                //选择指定库区;
                storages = storages.Where(s => areaCodes.Any(a => a == s.Cell.AreaCode));
            }
            else
            {
                storages = storages.Where(s => s.Cell.Area.AllotOutOrder > 0);
            }
            storages = storages.Where(s => string.IsNullOrEmpty(s.LockTag) && s.Cell.IsActive == "1" &&
                                      s.Quantity - s.OutFrozenQuantity > 0);

            foreach (var billDetail in billDetails)
            {
                //1:主库区 1;2:件烟区 2;
                //3;条烟区 3;4:暂存区 4;
                //5:备货区 0;6:残烟区 0;
                //7:罚烟区 0;8:虚拟区 0;
                //9:其他区 0;

                //分配整盘;排除 件烟区 条烟区
                string[] areaTypes = new string[] { "2", "3", "5" };
                var      ss        = storages.Where(s => areaTypes.All(a => a != s.Cell.Area.AreaType) &&
                                                    s.ProductCode == billDetail.ProductCode)
                                     .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotPallet(billMaster, billDetail, ss, cancellationToken, ps);

                //分配件烟;件烟区
                areaTypes = new string[] { "2" };
                ss        = storages.Where(s => areaTypes.Any(a => a == s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode)
                            .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotPiece(billMaster, billDetail, ss, cancellationToken, ps);

                //分配件烟 (下层储位);排除 件烟区 条烟区
                areaTypes = new string[] { "2", "3", "5" };
                ss        = storages.Where(s => areaTypes.All(a => a != s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode &&
                                           s.Cell.Layer == 1)
                            .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotPiece(billMaster, billDetail, ss, cancellationToken, ps);

                //分配件烟 (非下层储位);排除 件烟区 条烟区
                areaTypes = new string[] { "2", "3", "5" };
                ss        = storages.Where(s => areaTypes.All(a => a != s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode &&
                                           s.Cell.Layer != 1)
                            .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotPiece(billMaster, billDetail, ss, cancellationToken, ps);

                //分配条烟;条烟区
                areaTypes = new string[] { "3" };
                ss        = storages.Where(s => areaTypes.Any(a => a == s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode)
                            .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotBar(billMaster, billDetail, ss, cancellationToken, ps);

                //分配条烟;件烟区
                areaTypes = new string[] { "2" };
                ss        = storages.Where(s => areaTypes.Any(a => a == s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode)
                            .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotBar(billMaster, billDetail, ss, cancellationToken, ps);

                //分配条烟 (主库区下层);
                areaTypes = new string[] { "1" };
                ss        = storages.Where(s => areaTypes.All(a => a == s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode &&
                                           s.Cell.Layer == 1)
                            .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotBar(billMaster, billDetail, ss, cancellationToken, ps);

                //分配条烟 (主库区)
                areaTypes = new string[] { "1" };
                ss        = storages.Where(s => areaTypes.All(a => a == s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode &&
                                           s.Cell.Layer != 1)
                            .OrderBy(s => new { s.Cell.Area.AllotOutOrder, s.StorageTime });
                AllotBar(billMaster, billDetail, ss, cancellationToken, ps);

                //分配条烟 (暂存区)
                areaTypes = new string[] { "4" };
                ss        = storages.Where(s => areaTypes.All(a => a == s.Cell.Area.AreaType) &&
                                           s.ProductCode == billDetail.ProductCode)
                            .OrderBy(s => s.StorageTime)
                            .OrderBy(s => s.Cell.Area.AllotOutOrder);
                AllotBar(billMaster, billDetail, ss, cancellationToken, ps);

                if (billDetail.BillQuantity > billDetail.AllotQuantity)
                {
                    ps.State = StateType.Warning;
                    ps.Errors.Add(billDetail.ProductCode + " " + billDetail.Product.ProductName + ",库存不足!" + "订单量:" + billDetail.BillQuantity / billDetail.Product.Unit.Count + "(件)," + "未分配量:" + (billDetail.BillQuantity - billDetail.RealQuantity) / billDetail.Product.Unit.Count + "(件)");
                }
            }

            string billno = billMaster.BillNo;

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

                OutBillMasterRepository.GetObjectSet()
                .UpdateEntity(i => i.BillNo == billno,
                              i => new OutBillMaster()
                {
                    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
                {
                    OutBillMasterRepository.GetObjectSet()
                    .UpdateEntity(i => i.BillNo == billno,
                                  i => new OutBillMaster()
                    {
                        LockTag = ""
                    });
                }
            }
        }