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 = "" }); } } }