dengjunjie
2025-10-24 d4fc143136f77f0bb68e0ec7579d250a6ae550b6
优化出库单分配逻辑及平库出库任务生成
已修改2个文件
315 ■■■■■ 文件已修改
新建文件夹/WIDESEA_WMSServer/WIDESEA_SquareCabinServices/DeliveryOrderServices.cs 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
新建文件夹/WIDESEA_WMSServer/WIDESEA_SquareCabinServices/extend/Allocat.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
н¨Îļþ¼Ð/WIDESEA_WMSServer/WIDESEA_SquareCabinServices/DeliveryOrderServices.cs
@@ -365,31 +365,334 @@
                    };
                    BaseDal.Db.InsertNav(entityOrder).Include(x => x.Details).ExecuteCommand();
                    #endregion
                    List<Dt_InventoryInfo> dt_InventoryInfos = new List<Dt_InventoryInfo>();
                    #region å¤„理库存、添加出库任务
                    #region å¤„理库存、库存批次、添加出库任务
                    foreach (var item in entityOrder.Details)
                    {
                        dt_InventoryInfos = _inventoryInfoService.Repository.QueryData(x => x.MaterielCode == item.Goods_no && x.StockStatus == StockStatusEmun.入库完成.ObjToInt() && x.StockQuantity > x.OutboundQuantity && x.WarehouseCode == item.Reservoirarea);
                        Dt_Inventory_Batch inventory_Batch = _inventory_BatchServices.Repository.QueryFirst(x => x.MaterielCode == item.Goods_no && x.BatchNo == item.Batch_num);
                        if (inventory_Batch == null) throw new Exception($"未找到出库单号【{entityOrder.Out_no}】中物料编号【{item.Goods_no}】物料批次【{item.Batch_num}】的库存批次信息");
                        if (inventory_Batch.AvailableQuantity < item.Order_qty) throw new Exception($"出库单号【{entityOrder.Out_no}】中物料编号【{item.Goods_no}】物料批次【{item.Batch_num}】的库存批次信息可用数量不足");
                        inventory_Batch.AvailableQuantity -= item.Order_qty;
                        inventory_Batch.OutboundQuantity += item.Order_qty;
                        List<Dt_InventoryInfo> dt_InventoryInfos = _inventoryInfoService.Repository.QueryData(x => x.MaterielCode == item.Goods_no && x.BatchNo == item.Batch_num && x.StockStatus == StockStatusEmun.入库完成.ObjToInt() && x.StockQuantity > x.OutboundQuantity && x.WarehouseCode == item.Reservoirarea);
                        #region æŒ‰å‡ºåº“策略查找库存
                        if (tactics.SelectTactice == TacticsEnum.ComeOutonFirstTime.ObjToInt())
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.ValidityPeriod).ToList();
                        else
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.InDate).ToList();
                        #endregion
                        var Order_qty = item.Order_qty;
                        var Order_qty = item.Order_qty;//出库单数量
                        foreach (var InventoryInfo in dt_InventoryInfos)
                        {
                            if (Order_qty <= 0) break;
                            if (InventoryInfo.AvailableQuantity < Order_qty)
                            {
                                InventoryInfo.AvailableQuantity = 0;
                                Order_qty -= InventoryInfo.AvailableQuantity;
                                InventoryInfo.OutboundQuantity += InventoryInfo.AvailableQuantity;
                                InventoryInfo.StockStatus = StockStatusEmun.出库锁定.ObjToInt();
                            }
                            else
                            {
                                InventoryInfo.AvailableQuantity -= Order_qty;
                                Order_qty = 0;
                                InventoryInfo.OutboundQuantity += Order_qty;
                                InventoryInfo.StockStatus = StockStatusEmun.出库锁定.ObjToInt();
                            }
                        }
                        dt_InventoryInfos = dt_InventoryInfos.Where(X => X.StockStatus == StockStatusEmun.出库锁定.ObjToInt()).ToList();
                        List<Dt_SupplyTask> supplyTasks = new List<Dt_SupplyTask>();
                        foreach (var inventoryInfo in dt_InventoryInfos)
                        {
                            Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                            {
                                WarehouseCode = inventoryInfo.WarehouseCode,
                                BatchNo = inventoryInfo.BatchNo,
                                MaterielName = inventoryInfo.MaterielName,
                                MaterielCode = inventoryInfo.MaterielCode,
                                MaterielSpec = inventoryInfo.MaterielSpec,
                                TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                TaskType = TaskTypeEnum.OutPick.ObjToInt(),
                                CreateDate = DateTime.Now,
                                Creater = App.User.UserName ?? "System",
                                LocationCode = inventoryInfo.LocationCode,
                                OrderNo = entityOrder.Out_no,
                                StockQuantity = inventoryInfo.OutboundQuantity,
                                SupplyQuantity = 0,
                                Remark = "出库"
                            };
                            supplyTasks.Add(supplyTask);
                        }
                        _inventory_BatchServices.Repository.UpdateData(inventory_Batch);
                        _inventoryInfoService.Repository.UpdateData(dt_InventoryInfos);
                        _supplyTaskService.AddData(supplyTasks);
                    }
                    #endregion
                }
                else
                {
                    #region åˆ›å»ºå¤§ä»¶åº“、立库出库头表
                    var entityOrder = new Dt_DeliveryOrder
                    {
                        Out_no = outorder.order_no,
                        Out_type = outorder.order_type,
                        OutStatus = "新建",
                        Client_name = outorder.client_name,
                        Account_time = outorder.account_time,
                        Client_no = outorder.client_no,
                        Warehouse_no = WarehouseEnum.大件库.ObjToInt().ToString("000"),
                        Details = new List<Dt_DeliveryOrderDetail>()
                    };
                    var entityOrderLK = new Dt_DeliveryOrder
                    {
                        Out_no = outorder.order_no,
                        Out_type = outorder.order_type,
                        OutStatus = "新建",
                        Client_name = outorder.client_name,
                        Account_time = outorder.account_time,
                        Client_no = outorder.client_no,
                        Warehouse_no = WarehouseEnum.立库.ObjToInt().ToString("000"),
                        Details = new List<Dt_DeliveryOrderDetail>()
                    };
                    #endregion
                    #region æŸ¥æ‰¾åº“å­˜
                    foreach (var detail in outorder.details)
                    {
                        #region æŸ¥è¯¢åº“存批次和库存
                        Dt_Inventory_Batch inventory_Batch = _inventory_BatchServices.Repository.QueryFirst(x => x.MaterielCode == detail.goods_no && x.BatchNo == detail.batch_num);
                        if (inventory_Batch == null) throw new Exception($"未找到出库单号【{outorder.order_no}】中物料编号【{detail.goods_no}】物料批次【{detail.batch_num}】的库存批次信息");
                        if (inventory_Batch.AvailableQuantity < detail.order_qty) throw new Exception($"出库单号【{outorder.order_no}】中物料编号【{detail.goods_no}】物料批次【{detail.batch_num}】的库存批次信息可用数量不足");
                        inventory_Batch.AvailableQuantity -= detail.order_qty;
                        inventory_Batch.OutboundQuantity += detail.order_qty;
                        List<Dt_InventoryInfo> dt_InventoryInfos = _inventoryInfoService.Repository.QueryData(x => x.MaterielCode == inventory_Batch.MaterielCode && x.BatchNo == inventory_Batch.BatchNo && x.StockStatus == StockStatusEmun.入库完成.ObjToInt() && x.StockQuantity > x.OutboundQuantity && (x.WarehouseCode == WarehouseEnum.大件库.ObjToInt().ToString("000") || x.WarehouseCode == WarehouseEnum.立库.ObjToInt().ToString("000")));
                        #endregion
                        #region æŒ‰å‡ºåº“策略查找库存
                        if (tactics.SelectTactice == TacticsEnum.ComeOutonFirstTime.ObjToInt())
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.ValidityPeriod).ToList();
                        else
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.InDate).ToList();
                        #endregion
                        var Order_qty = Math.Abs(detail.order_qty);//出库单数量
                        #region æ ¹æ®ç‰©æ–™ç¼–码查询物料信息
                        Dt_MaterielInfo materielInfo = _basicService.MaterielInfoService.Repository.QueryFirst(x => x.MaterielCode == detail.goods_no);
                        if (materielInfo == null) throw new Exception($"未找到药品编码【{detail.goods_no}】的信息");
                        if (!Enum.IsDefined(typeof(MaterielSourceTypeEnum), materielInfo.MaterielSourceType))
                            throw new Exception($"请设置药品编号【{detail.goods_no}】的属性分类");
                        if (materielInfo.BoxQty < 1) throw new Exception($"请设置药品编号【{detail.goods_no}】的箱规数量");
                        #endregion
                        #region å¤§ä»¶
                        if (materielInfo.MaterielSourceType == MaterielSourceTypeEnum.PurchasePart)//如果物料是大件
                        {
                            #region æ·»åŠ å‡ºåº“è¯¦æƒ…
                            Dt_DeliveryOrderDetail orderDetail = new Dt_DeliveryOrderDetail()
                            {
                                Reservoirarea = entityOrder.Warehouse_no,
                                Goods_no = detail.goods_no,
                                Order_qty = detail.order_qty,
                                Batch_num = detail.batch_num,
                                Exp_date = detail.exp_date,
                                OotDetailStatus = "新建",
                                Order_Outqty = 0,
                                Status = 2
                            };
                            entityOrder.Details.Add(orderDetail);
                            #endregion
                            #region è®¡ç®—库存
                            foreach (var InventoryInfo in dt_InventoryInfos)
                            {
                                if (Order_qty <= 0) break;
                                if (InventoryInfo.AvailableQuantity < Order_qty)
                                {
                                    InventoryInfo.AvailableQuantity = 0;
                                    Order_qty -= InventoryInfo.AvailableQuantity;
                                    InventoryInfo.OutboundQuantity += InventoryInfo.AvailableQuantity;
                                    InventoryInfo.StockStatus = StockStatusEmun.出库锁定.ObjToInt();
                                }
                                else
                                {
                                    InventoryInfo.AvailableQuantity -= Order_qty;
                                    Order_qty = 0;
                                    InventoryInfo.OutboundQuantity += Order_qty;
                                    InventoryInfo.StockStatus = StockStatusEmun.出库锁定.ObjToInt();
                                }
                            }
                            #endregion
                            #region ç”Ÿæˆå‡ºåº“任务
                            dt_InventoryInfos = dt_InventoryInfos.Where(X => X.StockStatus == StockStatusEmun.出库锁定.ObjToInt()).ToList();
                            List<Dt_SupplyTask> supplyTasks = new List<Dt_SupplyTask>();
                            foreach (var inventoryInfo in dt_InventoryInfos)
                            {
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    WarehouseCode = inventoryInfo.WarehouseCode,
                                    BatchNo = inventoryInfo.BatchNo,
                                    MaterielName = inventoryInfo.MaterielName,
                                    MaterielCode = inventoryInfo.MaterielCode,
                                    MaterielSpec = inventoryInfo.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = TaskTypeEnum.OutPick.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = inventoryInfo.LocationCode,
                                    OrderNo = entityOrder.Out_no,
                                    StockQuantity = inventoryInfo.OutboundQuantity,
                                    SupplyQuantity = 0,
                                    Remark = "出库"
                                };
                                supplyTasks.Add(supplyTask);
                            }
                            #endregion
                            _inventory_BatchServices.Repository.UpdateData(inventory_Batch);
                            _inventoryInfoService.Repository.UpdateData(dt_InventoryInfos);
                            _supplyTaskService.AddData(supplyTasks);
                        }
                        #endregion
                        else
                        {
                            Dt_DeliveryOrderDetail orderDetail = null;
                            Dt_DeliveryOrderDetail orderDetailLK = null;
                            var ys = Order_qty % materielInfo.BoxQty; //不能整除箱规的散件数
                            var xs = (int)(Order_qty / materielInfo.BoxQty);//保留整数
                            #region æ•£ä»¶ä¼˜å…ˆåˆ†é…ç«‹åº“
                            if (ys > 0)
                            {
                                orderDetailLK = new Dt_DeliveryOrderDetail()
                                {
                                    Reservoirarea = entityOrderLK.Warehouse_no,
                                    Goods_no = detail.goods_no,
                                    Order_qty = ys,
                                    Batch_num = detail.batch_num,
                                    Exp_date = detail.exp_date,
                                    OotDetailStatus = "新建",
                                    Order_Outqty = 0,
                                    Status = 0
                                };
                            }
                            #endregion
                            #region æ•´ä»¶ä¼˜å…ˆåˆ†é…å¤§ä»¶åº“
                            foreach (var item in dt_InventoryInfos.Where(x => x.WarehouseCode == WarehouseEnum.大件库.ObjToInt().ToString("000")))
                            {
                                if (xs <= 0) break;
                                item.StockStatus = StockStatusEmun.出库锁定.ObjToInt();
                                while (item.AvailableQuantity > 0 && xs > 0)
                                {
                                    xs--;
                                    if (orderDetail == null)
                                    {
                                        orderDetail = new Dt_DeliveryOrderDetail()
                                        {
                                            Reservoirarea = entityOrder.Warehouse_no,
                                            Goods_no = detail.goods_no,
                                            Order_qty = materielInfo.BoxQty,
                                            Batch_num = detail.batch_num,
                                            Exp_date = detail.exp_date,
                                            OotDetailStatus = "新建",
                                            Order_Outqty = 0,
                                            Status = 0
                                        };
                                        item.AvailableQuantity -= materielInfo.BoxQty;
                                        item.OutboundQuantity += materielInfo.BoxQty;
                                    }
                                    else
                                    {
                                        orderDetail.Order_qty += materielInfo.BoxQty;
                                        item.AvailableQuantity -= materielInfo.BoxQty;
                                        item.OutboundQuantity += materielInfo.BoxQty;
                                    }
                                }
                            }
                            #endregion
                            #region åˆ†é…å®Œå¤§ä»¶åº“如果还有箱数,再选择分配立库
                            if (orderDetailLK == null)
                            {
                                orderDetailLK = new Dt_DeliveryOrderDetail()
                                {
                                    Reservoirarea = entityOrderLK.Warehouse_no,
                                    Goods_no = detail.goods_no,
                                    Order_qty = xs * materielInfo.BoxQty,
                                    Batch_num = detail.batch_num,
                                    Exp_date = detail.exp_date,
                                    OotDetailStatus = "新建",
                                    Order_Outqty = 0,
                                    Status = 0
                                };
                            }
                            else
                            {
                                orderDetailLK.Order_qty += xs * materielInfo.BoxQty;
                            }
                            #endregion
                            List<Dt_SupplyTask> supplyTasks = new List<Dt_SupplyTask>();
                            if (orderDetailLK != null)
                            {
                                #region æ·»åŠ å‡ºåº“ä»»åŠ¡ã€ä¿®æ”¹åº“å­˜ä¿¡æ¯
                                Dt_InventoryInfo inventoryInfo = dt_InventoryInfos.Where(x => x.WarehouseCode == WarehouseEnum.立库.ObjToInt().ToString("000")).First();
                                inventoryInfo.AvailableQuantity -= orderDetailLK.Order_qty;
                                inventoryInfo.OutboundQuantity += orderDetailLK.Order_qty;
                                inventoryInfo.StockStatus = StockStatusEmun.出库锁定.ObjToInt();
                                _inventoryInfoService.Repository.UpdateData(inventoryInfo);
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    WarehouseCode = inventoryInfo.WarehouseCode,
                                    BatchNo = inventoryInfo.BatchNo,
                                    MaterielName = inventoryInfo.MaterielName,
                                    MaterielCode = inventoryInfo.MaterielCode,
                                    MaterielSpec = inventoryInfo.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = TaskTypeEnum.OutPick.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = inventoryInfo.LocationCode,
                                    OrderNo = entityOrder.Out_no,
                                    StockQuantity = inventoryInfo.OutboundQuantity,
                                    SupplyQuantity = 0,
                                    Remark = "出库"
                                };
                                supplyTasks.Add(supplyTask);
                                #endregion
                                entityOrderLK.Details.Add(orderDetailLK);
                            }
                            if (orderDetail != null)
                            {
                                #region æ·»åŠ å‡ºåº“ä»»åŠ¡ã€ä¿®æ”¹åº“å­˜ä¿¡æ¯
                                dt_InventoryInfos = dt_InventoryInfos.Where(X => X.StockStatus == StockStatusEmun.出库锁定.ObjToInt()).ToList();
                                foreach (var inventoryInfo in dt_InventoryInfos)
                                {
                                    Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                    {
                                        WarehouseCode = inventoryInfo.WarehouseCode,
                                        BatchNo = inventoryInfo.BatchNo,
                                        MaterielName = inventoryInfo.MaterielName,
                                        MaterielCode = inventoryInfo.MaterielCode,
                                        MaterielSpec = inventoryInfo.MaterielSpec,
                                        TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                        TaskType = TaskTypeEnum.OutPick.ObjToInt(),
                                        CreateDate = DateTime.Now,
                                        Creater = App.User.UserName ?? "System",
                                        LocationCode = inventoryInfo.LocationCode,
                                        OrderNo = entityOrder.Out_no,
                                        StockQuantity = inventoryInfo.OutboundQuantity,
                                        SupplyQuantity = 0,
                                        Remark = "出库"
                                    };
                                    supplyTasks.Add(supplyTask);
                                }
                                #endregion
                                entityOrder.Details.Add(orderDetail);
                            }
                            _inventory_BatchServices.Repository.UpdateData(inventory_Batch);
                            _inventoryInfoService.Repository.UpdateData(dt_InventoryInfos);
                            _supplyTaskService.AddData(supplyTasks);
                        }
                    }
                    if (entityOrder.Details.Count > 0)
                        BaseDal.Db.InsertNav(entityOrder).Include(x => x.Details).ExecuteCommand();
                    if (entityOrderLK.Details.Count > 0)
                        BaseDal.Db.InsertNav(entityOrderLK).Include(x => x.Details).ExecuteCommand();
                    #endregion
                }
            }
            catch (Exception ex)
н¨Îļþ¼Ð/WIDESEA_WMSServer/WIDESEA_SquareCabinServices/extend/Allocat.cs
@@ -51,7 +51,9 @@
                    }
                    item.AvailableQuantity = item.StockQuantity - item.OutboundQuantity;
                }
                #region å¤§ä»¶åº“补立库后立库业务库存数还是小于立库最小库存数,添加提示信息
                #endregion
                #region æ·»åŠ è°ƒæ‹¨å‡ºåº“å•
                Dt_DeliveryOrder deliveryOrder = new Dt_DeliveryOrder()
                {