Ejemplo n.º 1
0
        /// <summary>
        ///     存、退、还
        /// </summary>
        /// <param name="exchanges"></param>
        /// <param name="boxes"></param>
        /// <param name="priority"></param>
        /// <param name="extension">扩展未占位药盒</param>
        /// <param name="cross">跨抽屉或跨柜子</param>
        internal void LocateCheckIn(ref Exchange[] exchanges, List <BoxDevice> boxes, bool extension, bool cross, LocatePriority priority = LocatePriority.CabinetFirst)
        {
            InitSchedule(exchanges);
            foreach (var exchange in exchanges)
            {
                List <(BoxDevice Box, NodeGoodsInfo Node)> options;
                if (extension)
                {
                    // 组合
                    // 1. 相同物品[GoodsId]且无现存量,2. 未占位且同类药盒,3. 不同物品[GoodsId]且无现存量(保留一个占位),4. 相同物品[GoodsId 批号 有效期]且有现存量
                    var box2 = new List <BoxDevice>();
                    var box3 = new List <BoxDevice>();

                    var box1     = boxes.Where(b => b.Fills.Any(f => f.GoodsId == exchange.GoodsId && f.QtyExisted == 0)).ToList();
                    var box4     = boxes.Where(b => b.Fills.Any(f => f.QtyExisted > 0 && CanCheckIn(f, exchange.GoodsId, exchange.BatchNumber, exchange.ExpiredDate))).ToList();
                    var goodsbox = box1.Concat(box4).FirstOrDefault();

                    box2 = boxes.Where(b => b.Fills.Count() == 0 && IsSimilarBox(goodsbox, b, cross)).Select(b => { b.Fills = goodsbox?.Fills.Select(f => new NodeGoodsInfo {
                            GoodsId = f.GoodsId, Goods = f.Goods, Barcodes = f.Barcodes, BatchNumber = f.BatchNumber, ExpiredDate = f.ExpiredDate, QtyExisted = 0, QtyMax = f.QtyMax, StorageTime = f.StorageTime
                        }).ToList(); return(b); }).ToList();

                    var different    = boxes.Where(b => b.Fills.All(f => f.QtyExisted == 0 && f.GoodsId != exchange.GoodsId) && IsSimilarBox(goodsbox, b, cross)).ToList();
                    var exist        = boxes.Where(b => b.Fills.Any(f => f.QtyExisted > 0) && IsSimilarBox(goodsbox, b, cross)).ToList();
                    var newdifferent = new List <BoxDevice>();
                    foreach (var item in different)
                    {
                        if (!newdifferent.Where(n => n.Fills.Select(f => new { f.GoodsId, f.BatchNumber, f.ExpiredDate }).OrderBy(o => o.GoodsId).SequenceEqual(item.Fills.Select(f => new { f.GoodsId, f.BatchNumber, f.ExpiredDate }).OrderBy(o => o.GoodsId))).Any())
                        {
                            newdifferent.Add(item);
                        }
                    }

                    foreach (var item in newdifferent)
                    {
                        if (!exist.Where(b => b.Fills.Select(f => new { f.GoodsId, f.BatchNumber, f.ExpiredDate }).OrderBy(o => o.GoodsId).SequenceEqual(item.Fills.Select(f => new { f.GoodsId, f.BatchNumber, f.ExpiredDate }).OrderBy(o => o.GoodsId))).Any())
                        {
                            different.Remove(item);
                        }
                    }
                    box3 = different.Select(b => { b.Fills = goodsbox?.Fills.Select(f => new NodeGoodsInfo {
                            GoodsId = f.GoodsId, Goods = f.Goods, Barcodes = f.Barcodes, BatchNumber = f.BatchNumber, ExpiredDate = f.ExpiredDate, QtyExisted = 0, QtyMax = f.QtyMax, StorageTime = f.StorageTime
                        }).ToList(); return(b); }).ToList();

                    options = box1.Concat(box2).Concat(box3).Concat(box4).Select(b => (b, b.Fills.First(f => f.GoodsId == exchange.GoodsId))).ToList();
                }
                else
                {
                    // 优先填充取量少的
                    options = boxes.Where(b => b.Fills.Any(f => CanCheckIn(f, exchange.GoodsId, exchange.BatchNumber, exchange.ExpiredDate)))
                              .Select(b => (Box: b, Node: b.Fills.First(f => f.GoodsId == exchange.GoodsId))).OrderBy(o => o.Node.QtyMax - o.Node.QtyExisted).ToList();
                }

                switch (priority)
                {
                case LocatePriority.CabinetFirst:
                    options = options.Where(o => o.Box.BoxMode != BoxMode.VirtualBox).Concat(options.Where(o => o.Box.BoxMode == BoxMode.VirtualBox)).ToList();
                    break;

                case LocatePriority.VirtualFirst:
                    options = options.Where(o => o.Box.BoxMode == BoxMode.VirtualBox).Concat(options.Where(o => o.Box.BoxMode != BoxMode.VirtualBox)).ToList();
                    break;
                }
                foreach (var option in options)
                {
                    var qty = exchange.Qty - exchange.Plans.Sum(p => p.Qty);
                    if (qty > 0)
                    {
                        var plan = new ActionPlan {
                            Box = option.Box, Mode = ExchangeMode.CheckIn, Qty = Math.Min(qty, option.Node.QtyMax - option.Node.QtyExisted), IsExecuted = false,
                        };
                        exchange.Plans.Add(plan);
                        option.Node.QtyExisted += plan.Qty;
                    }
                }
            }
        }