Demo
2024-04-01 963f2f00f033d3fdd3d18ab71beb28d9f0e179bf
Wms/WMS.BLL/Logic/AllotSku.cs
@@ -233,6 +233,386 @@
        /// <summary>
        /// 原辅料取样出库分配库存
        /// </summary>
        /// <param name="palletList">托盘明细</param>
        /// <param name="boxInfoList">箱码明细</param>
        /// <param name="needQty">需求数</param>
        /// <param name="stockQtyDic">托出库物品数</param>
        /// <param name="useBoxQtyDic">托出库物品数</param>
        /// <param name="type">取样类型1:规则取样 2:随机取样</param>
        /// <param name="boxNum">需分配的箱数量  随机取样用</param>
        /// <param name="pickNum"></param>
        /// <returns></returns>
        public decimal AllotPalletsQuYang(List<DataStockDetail> palletList, List<DataBoxInfo> boxInfoList, decimal needQty, Dictionary<int, decimal> stockQtyDic, Dictionary<int, decimal> useBoxQtyDic, string type, int boxNum, decimal pickNum)
        {
            try
            {
                decimal? qty = 0;
                var listOrder = boxInfoList.Where(m => m.IsDel == "0").OrderBy(m => m.BoxNo).ThenBy(m => m.Qty).ToList();//根据箱码、数量排序 整箱的
                var boxList = listOrder.GroupBy(m => m.BoxNo).Select(m => m.Key).ToList();//分组后的箱码集合
                var boxCount = boxList.Count();//箱数量
                #region 旧分配原则
                //var outInfoCount = 0;
                //var boxStrList = new List<string>();//随机使用箱
                //Dictionary<string, decimal> useInfoQtyDic = new Dictionary<string, decimal>();//使用箱
                //if (type == "1")//规则取样(N<3;3<N<300;300<N)
                //{
                //    if (boxCount<=3)//箱子小于3
                //    {
                //        foreach (var item in boxList)//循环箱子
                //        {
                //            boxStrList.Add(item);
                //        }
                //    }
                //    else if (boxCount > 3)//箱子小于3
                //    {
                //        var a = Math.Sqrt(boxCount)+1;//开平方 //规则 箱数 √N+1
                //        if (boxCount > 300)
                //        {
                //            a = Math.Sqrt(boxCount) / 2 + 1;//规则 箱数 √N/2+1
                //        }
                //        var b = Math.Floor(a); //取样的箱数
                //        var lit = new List<int>();
                //        do
                //        {
                //            byte[] buffer = Guid.NewGuid().ToByteArray();
                //            int iSeed = BitConverter.ToInt32(buffer, 0);
                //            Random random = new Random(iSeed);
                //            var j = random.Next(0, boxCount);
                //            if (lit.Contains(j))
                //            {
                //                continue;
                //            }
                //            var boxCode = boxList[j];//箱码
                //            boxStrList.Add(boxCode);
                //            lit.Add(j);
                //        } while (lit.Count < b);
                //    }
                //}
                //else if(type == "2") //随机取样(一批次出一箱)
                //{
                //    if (boxCount < boxNum)
                //    {
                //        throw new Exception("当前库存整箱数少于输入的取样数");
                //    }
                //    var lit = new List<int>();
                //    do
                //    {
                //        byte[] buffer = Guid.NewGuid().ToByteArray();
                //        int iSeed = BitConverter.ToInt32(buffer, 0);
                //        Random random = new Random(iSeed);
                //        var j = random.Next(0, boxCount);
                //        if (lit.Contains(j))
                //        {
                //            continue;
                //        }
                //        var boxCode = boxList[j];//箱码
                //        boxStrList.Add(boxCode);
                //        lit.Add(j);
                //    } while (lit.Count < boxNum);
                //}
                //else
                //{
                //    throw new Exception("请选择取样规则");
                //}
                //foreach (var item in boxStrList)//循环箱子
                //{
                //    var box = listOrder.Where(m => m.BoxCode == item).ToList();
                //    var infoCount = box.Count;//箱内支数量
                //    if (infoCount <= 3) //支数量<=3
                //    {
                //        outInfoCount += infoCount;
                //        SaveDic(useInfoQtyDic, item, infoCount);
                //    }
                //    else if (infoCount > 3)//箱内数量 > 3 且 <=300
                //    {
                //        //规则 取样支数 √N+1
                //        var c = Math.Sqrt(infoCount) + 1;//开平方
                //        if (infoCount > 300) //箱内数量 > 300
                //        {
                //            //规则 箱数 √N/2+1
                //            c = Math.Sqrt(infoCount) / 2 + 1;
                //        }
                //        var d = Math.Floor(c);  //取样的支数量
                //        outInfoCount += (int)d;
                //        SaveDic(useInfoQtyDic, item, (decimal)d);
                //    }
                //}
                //var pingJunNum = needQty / outInfoCount;//平均每支取的数量
                //foreach (var item in useInfoQtyDic)
                //{
                //    var box = listOrder.Where(m => m.BoxCode == item.Key).ToList();
                //    var infoCount = box.Count;//箱内支数量
                //    if (infoCount <= 3) //支数量<=3
                //    {
                //        foreach (var item2 in box)
                //        {
                //            if (pingJunNum >= item2.Qty)
                //            {
                //                throw new Exception("平均需取样数量大于等于箱支内数量");
                //            }
                //            qty += pingJunNum;
                //            var tray = palletList.First(m => m.Id == item2.TrayId);
                //            SaveDic(stockQtyDic, tray.Id, pingJunNum);
                //            SaveDic(useBoxQtyDic, item2.Id, pingJunNum);
                //        }
                //    }
                //    else if (infoCount > 3)//箱内数量 > 3 且 <=300
                //    {
                //        var e = item.Value; //取样的支数量
                //        var lit2 = new List<int>();
                //        do
                //        {
                //            byte[] buffer = Guid.NewGuid().ToByteArray();
                //            int iSeed = BitConverter.ToInt32(buffer, 0);
                //            Random random = new Random(iSeed);
                //            var j = random.Next(0, infoCount);//随机箱内支码
                //            if (lit2.Contains(j))
                //            {
                //                continue;
                //            }
                //            var info = box[j];
                //            if (pingJunNum >= info.Qty)
                //            {
                //                throw new Exception("平均需取样数量大于等于箱支内数量");
                //            }
                //            qty += pingJunNum;
                //            var tray = palletList.First(m => m.Id == info.TrayId);
                //            SaveDic(stockQtyDic, tray.Id, pingJunNum);
                //            SaveDic(useBoxQtyDic, info.Id, pingJunNum);
                //            lit2.Add(j);
                //        } while (lit2.Count < e);
                //    }
                //}
                #endregion
                var outInfoCount = 0;
                var boxStrList = new List<string>();//随机使用箱
                Dictionary<string, int> useInfoQtyDic = new Dictionary<string, int>();//使用箱 及每箱出多少支
                if (type == "1")//规则取样(N<3;3<N<300;300<N)
                {
                    if (boxCount <= 3)//箱子小于3
                    {
                        foreach (var item in boxList)//循环箱子
                        {
                            boxStrList.Add(item);
                        }
                    }
                    else if (boxCount > 3)//箱子小于3
                    {
                        var a = Math.Sqrt(boxCount) + 1;//开平方 //规则 箱数 √N+1
                        if (boxCount > 300)
                        {
                            a = Math.Sqrt(boxCount) / 2 + 1;//规则 箱数 √N/2+1
                        }
                        var b = Math.Floor(a); //取样的箱数
                        var lit = new List<int>();
                        do
                        {
                            byte[] buffer = Guid.NewGuid().ToByteArray();
                            int iSeed = BitConverter.ToInt32(buffer, 0);
                            Random random = new Random(iSeed);
                            var j = random.Next(0, boxCount);
                            if (lit.Contains(j))
                            {
                                continue;
                            }
                            var boxCode = boxList[j];//箱码
                            boxStrList.Add(boxCode);
                            lit.Add(j);
                        } while (lit.Count < b);
                    }
                    var zhi = listOrder.Count();
                    if (zhi <= 3) //支数量<=3
                    {
                        outInfoCount += zhi;
                    }
                    else if (zhi > 3)//箱内数量 > 3 且 <=300
                    {
                        //规则 取样支数 √N+1
                        var c = Math.Sqrt(zhi) + 1;//开平方
                        if (zhi > 300) //箱内数量 > 300
                        {
                            //规则 箱数 √N/2+1
                            c = Math.Sqrt(zhi) / 2 + 1;
                        }
                        var d = Math.Floor(c);  //取样的支数量
                        outInfoCount += (int)d;
                    }
                }
                else if (type == "2") //随机取样(一批次出一箱)
                {
                    if (boxCount < boxNum)
                    {
                        throw new Exception("当前库存整箱数少于输入的取样数");
                    }
                    var lit = new List<int>();
                    do
                    {
                        byte[] buffer = Guid.NewGuid().ToByteArray();
                        int iSeed = BitConverter.ToInt32(buffer, 0);
                        Random random = new Random(iSeed);
                        var j = random.Next(0, boxCount);
                        if (lit.Contains(j))
                        {
                            continue;
                        }
                        var boxCode = boxList[j];//箱码
                        boxStrList.Add(boxCode);
                        lit.Add(j);
                    } while (lit.Count < boxNum);
                    var zhi = listOrder.Count(m => boxStrList.Contains(m.BoxNo));
                    if (zhi <= 3) //支数量<=3
                    {
                        outInfoCount += zhi;
                    }
                    else if (zhi > 3)//箱内数量 > 3 且 <=300
                    {
                        //规则 取样支数 √N+1
                        var c = Math.Sqrt(zhi) + 1;//开平方
                        if (zhi > 300) //箱内数量 > 300
                        {
                            //规则 箱数 √N/2+1
                            c = Math.Sqrt(zhi) / 2 + 1;
                        }
                        var d = Math.Floor(c);  //取样的支数量
                        outInfoCount += (int)d;
                    }
                }
                else
                {
                    throw new Exception("请选择取样规则");
                }
                var zhiCount = outInfoCount;
                var xiangCount = boxStrList.Count; //随机出的箱数量
                for (int i = 1; i <= boxStrList.Count; i++)
                {
                    decimal t = zhiCount / xiangCount;
                    var t2 = zhiCount % xiangCount;
                    var t3 = 5 / 2;
                    var t4 = 5 % 2;
                    if (t2 > 0)
                    {
                        t += 1;
                    }
                    var q = (int)t;//箱内出多少支
                    var infoCount = listOrder.Count(m => m.BoxNo == boxStrList[i - 1]);
                    if (q > infoCount)
                    {
                        throw new Exception("箱内支数小于要分配的支数");
                    }
                    zhiCount -= q;
                    xiangCount -= 1;
                    SaveDic2(useInfoQtyDic, boxStrList[i - 1], q);
                }
                var pingJunNum = needQty / outInfoCount;// / pickNum;平均每支取的数量
                foreach (var item in useInfoQtyDic)
                {
                    var box = listOrder.Where(m => m.BoxNo == item.Key).ToList();
                    var infoCount = box.Count;//箱内支数量
                    if (infoCount == item.Value) //支数量<=3
                    {
                        foreach (var item2 in box)
                        {
                            if (pingJunNum > item2.Qty)
                            {
                                throw new Exception("平均需取样数量大于等于箱支内数量");
                            }
                            qty += pingJunNum;
                            var tray = palletList.First(m => m.Id == item2.Id);
                            SaveDic(stockQtyDic, tray.Id, pingJunNum);
                            SaveDic(useBoxQtyDic, item2.Id, pingJunNum);
                        }
                    }
                    else
                    {
                        var e = item.Value; //取样的支数量
                        var lit2 = new List<int>();
                        do
                        {
                            byte[] buffer = Guid.NewGuid().ToByteArray();
                            int iSeed = BitConverter.ToInt32(buffer, 0);
                            Random random = new Random(iSeed);
                            var j = random.Next(0, infoCount);//随机箱内支码
                            if (lit2.Contains(j))
                            {
                                continue;
                            }
                            var info = box[j];
                            if (pingJunNum > info.Qty)
                            {
                                throw new Exception("平均需取样数量大于等于箱支内数量");
                            }
                            qty += pingJunNum;
                            var tray = palletList.First(m => m.Id == info.Id);
                            SaveDic(stockQtyDic, tray.Id, pingJunNum);
                            SaveDic(useBoxQtyDic, info.Id, pingJunNum);
                            lit2.Add(j);
                        } while (lit2.Count < e);
                    }
                }
                return (decimal)qty;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 保存字典
        /// </summary>
        /// <param name="dic"></param>
@@ -250,6 +630,18 @@
            }
        }
        private void SaveDic2(Dictionary<string, int> dic, string key, int v)
        {
            if (dic.ContainsKey(key))
            {
                dic[key] += v;
            }
            else
            {
                dic.Add(key, v);
            }
        }
        //--------------------------------------------------------------------------------------------------------------
        #region MyRegion