yanjinhui
2025-12-01 2b49f7643d15b74889d190f216630559006ed93a
н¨Îļþ¼Ð/WIDESEA_WMSServer/ClassLibrary2/Inventory_BatchServices.cs.cs
@@ -34,31 +34,176 @@
        }
        public IRepository<Dt_Inventory_Batch> Repository => BaseDal;
        /// <summary>
        /// è°ƒæ‹¨å•
        /// </summary>
        /// <param name="saveModel"></param>
        /// <returns></returns>
        //public override WebResponseContent UpdateData(SaveModel saveModel)
        //{
        //    try
        //    {
        //        string WareCode = WarehouseEnum.大件库.ObjToInt().ToString("000");
        //        var qty = saveModel.MainData["availableQuantity"].ObjToInt();
        //        var id = saveModel.MainData["id"].ObjToInt();
        //        var materielCode = saveModel.MainData["materielCode"].ToString();
        //        var batchNo = saveModel.MainData["batchNo"].ToString();
        //        //var Inventory_Batch = BaseDal.QueryFirst(x => x.Id == id);
        //        //if (qty > Inventory_Batch.AvailableQuantity) throw new Exception("调拨数量不可大于可用数量");
        //        var materielInfo = _materielInfoService.Repository.QueryFirst(x => x.MaterielCode == materielCode);
        //        if (materielInfo == null) return WebResponseContent.Instance.Error($"请维护药品编号【{materielCode}】的信息");
        //        if (!Enum.IsDefined(typeof(MaterielSourceTypeEnum), materielInfo.MaterielSourceType))
        //            return WebResponseContent.Instance.Error($"请设置药品编号【{materielCode}】的属性分类");
        //        if (materielInfo.MaterielSourceType == MaterielSourceTypeEnum.PurchasePart)
        //            return WebResponseContent.Instance.Error($"药品编号【{materielCode}】的属性分类为大件,不可调拨");
        //        List<Dt_InventoryInfo> dt_InventoryInfos = _inventoryInfoService.Repository.QueryData(x => x.MaterielCode == materielInfo.MaterielCode && x.BatchNo == batchNo && x.StockStatus == StockStatusEmun.入库完成.ObjToInt() && x.AvailableQuantity > 0 && x.WarehouseCode == WareCode).OrderBy(x => x.InDate).ToList();
        //        if (dt_InventoryInfos.Count < 1) return WebResponseContent.Instance.Error($"物料编号【{materielInfo.MaterielCode}】大件库无库存!请及时补充库存!");
        //        var StockQty = dt_InventoryInfos.Sum(x => x.AvailableQuantity);
        //        if (StockQty < qty) return WebResponseContent.Instance.Error($"调拨数量不可大于大件库可用数量,大件库可用数量为【{StockQty}】");
        //        var zx = (qty / materielInfo.BoxQty).ObjToInt();
        //        var ys = qty % materielInfo.BoxQty;
        //        if (ys > 0) zx++;
        //        decimal Qty = 0;
        //        List<Dt_SupplyTask> supplyTasks = new List<Dt_SupplyTask>();
        //        Dt_DeliveryOrder deliveryOrder = new Dt_DeliveryOrder()
        //        {
        //            Out_no = DateTime.Now.ToString("yyMMddHHmmss"),
        //            Warehouse_no = WareCode,
        //            Out_type = OutOrderTypeEnum.Allocate.ObjToInt().ToString(),
        //            OutStatus = "新建",
        //            Details = new List<Dt_DeliveryOrderDetail>()
        //        };
        //        foreach (var item in dt_InventoryInfos)
        //        {
        //            decimal taskQty = 0;
        //            if (zx < 1) break;
        //            while (item.AvailableQuantity > 0 && zx > 0)
        //            {
        //                zx--;
        //                Qty += materielInfo.BoxQty;
        //                taskQty += materielInfo.BoxQty;
        //                materielInfo.Business_qty += materielInfo.BoxQty;
        //                item.OutboundQuantity += materielInfo.BoxQty;
        //                item.AvailableQuantity -= materielInfo.BoxQty;
        //            }
        //            #region æ·»åŠ è°ƒæ‹¨å‡ºåº“ä»»åŠ¡
        //            Dt_SupplyTask supplyTask = new Dt_SupplyTask()
        //            {
        //                WarehouseCode = item.WarehouseCode,
        //                BatchNo = item.BatchNo,
        //                MaterielName = item.MaterielName,
        //                MaterielCode = item.MaterielCode,
        //                MaterielSpec = item.MaterielSpec,
        //                TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
        //                TaskType = TaskTypeEnum.AllocatOut.ObjToInt(),
        //                CreateDate = DateTime.Now,
        //                Creater = App.User.UserName ?? "System",
        //                LocationCode = item.LocationCode,
        //                OrderNo = deliveryOrder.Out_no,
        //                StockQuantity = taskQty,
        //                SupplyQuantity = 0,
        //                Remark = "调拨出库"
        //            };
        //            supplyTasks.Add(supplyTask);
        //            #endregion
        //        }
        //        Dt_DeliveryOrderDetail deliveryOrderDetail = new Dt_DeliveryOrderDetail()
        //        {
        //            Batch_num = batchNo,
        //            Order_Outqty = 0,
        //            Order_qty = Qty,
        //            CreateDate = DateTime.Now,
        //            Creater = App.User.UserName ?? "System",
        //            Goods_no = materielCode,
        //            OotDetailStatus = "新建",
        //            Status = 2,
        //            Reservoirarea = WareCode
        //        };
        //        deliveryOrder.Details.Add(deliveryOrderDetail);
        //        #region æ·»åŠ è°ƒæ‹¨å…¥åº“å•
        //        Dt_CabinOrder cabinOrder = new Dt_CabinOrder()
        //        {
        //            Order_no = deliveryOrder.Out_no,
        //            Order_type = InOrderTypeEnum.Allocat.ObjToInt().ToString(),
        //            Warehouse_no = "001",
        //            OdrderStatus = "新建",
        //            Details = new List<Dt_CabinOrderDetail>()
        //        };
        //        foreach (var item in deliveryOrder.Details)
        //        {
        //            Dt_CabinOrderDetail orderDetail = new Dt_CabinOrderDetail()
        //            {
        //                Reservoirarea = cabinOrder.Warehouse_no,
        //                Goods_no = item.Goods_no,
        //                Order_qty = item.Order_qty,
        //                Batch_num = item.Batch_num,
        //                OrderDetailStatus = "新建",
        //                Status = 0
        //            };
        //            cabinOrder.Details.Add(orderDetail);
        //        }
        //        #endregion
        //        Db.Ado.BeginTran();
        //        _materielInfoService.UpdateData(materielInfo);
        //        _inventoryInfoService.Repository.UpdateData(dt_InventoryInfos);
        //        _supplyTaskService.AddData(supplyTasks);
        //        if (deliveryOrder.Details.Count > 0) Db.InsertNav(deliveryOrder).Include(x => x.Details).ExecuteCommand();
        //        if (cabinOrder.Details.Count > 0) Db.InsertNav(cabinOrder).Include(x => x.Details).ExecuteCommand();
        //        Db.Ado.CommitTran();
        //        return WebResponseContent.Instance.OK("调拨出入库单生成成功,请操作调拨单");
        //    }
        //    catch (Exception ex)
        //    {
        //        Db.Ado.RollbackTran();
        //        return WebResponseContent.Instance.Error(ex.Message);
        //    }
        //}
        /// <summary>
        /// è°ƒæ‹¨å•
        /// </summary>
        /// <param name="saveModel"></param>
        /// <returns></returns>
        public override WebResponseContent UpdateData(SaveModel saveModel)
        {
            try
            {
                string WareCode = WarehouseEnum.大件库.ObjToInt().ToString("000");
                var qty = saveModel.MainData["availableQuantity"].ObjToInt();
                var id = saveModel.MainData["id"].ObjToInt();
                var qty = saveModel.MainData["availableQuantity"].ObjToInt();//用户输入的数量
                var id = saveModel.MainData["id"].ObjToInt();//库存批次的id
                var materielCode = saveModel.MainData["materielCode"].ToString();
                var batchNo = saveModel.MainData["batchNo"].ToString();
                //var Inventory_Batch = BaseDal.QueryFirst(x => x.Id == id);
                //if (qty > Inventory_Batch.AvailableQuantity) throw new Exception("调拨数量不可大于可用数量");
                var materielInfo = _materielInfoService.Repository.QueryFirst(x => x.MaterielCode == materielCode);
                if (materielInfo == null) return WebResponseContent.Instance.Error($"请维护药品编号【{materielCode}】的信息");
                if (!Enum.IsDefined(typeof(MaterielSourceTypeEnum), materielInfo.MaterielSourceType))
                    return WebResponseContent.Instance.Error($"请设置药品编号【{materielCode}】的属性分类");
                if (materielInfo.MaterielSourceType == MaterielSourceTypeEnum.PurchasePart)
                    return WebResponseContent.Instance.Error($"药品编号【{materielCode}】的属性分类为大件,不可调拨");
                List<Dt_InventoryInfo> dt_InventoryInfos = _inventoryInfoService.Repository.QueryData(x => x.MaterielCode == materielInfo.MaterielCode && x.BatchNo == batchNo && x.StockStatus == StockStatusEmun.入库完成.ObjToInt() && x.AvailableQuantity > 0 && x.WarehouseCode == WareCode).OrderBy(x => x.InDate).ToList();
                if (dt_InventoryInfos.Count < 1) return WebResponseContent.Instance.Error($"物料编号【{materielInfo.MaterielCode}】大件库无库存!请及时补充库存!");
                var StockQty = dt_InventoryInfos.Sum(x => x.AvailableQuantity);
                if (StockQty < qty) return WebResponseContent.Instance.Error($"调拨数量不可大于大件库可用数量,大件库可用数量为【{StockQty}】");
                var zx = (qty / materielInfo.BoxQty).ObjToInt();
                var ys = qty % materielInfo.BoxQty;
                if (ys > 0) zx++;
                decimal Qty = 0;
                // æ£€æŸ¥å¤§ä»¶åº“中是否存在散件
                decimal totalLooseQty = 0;
                foreach (var inventory in dt_InventoryInfos)
                {
                    var looseQty = inventory.AvailableQuantity % materielInfo.BoxQty;
                    if (looseQty > 0)
                    {
                        totalLooseQty += looseQty;
                    }
                }
                decimal Qty = 0; // å®žé™…调拨总数量
                decimal businessQtyToAdd = 0; // éœ€è¦æ·»åŠ åˆ°ä¸šåŠ¡æ•°é‡çš„æ•°é‡
                List<Dt_SupplyTask> supplyTasks = new List<Dt_SupplyTask>();
                Dt_DeliveryOrder deliveryOrder = new Dt_DeliveryOrder()
                {
@@ -68,40 +213,153 @@
                    OutStatus = "新建",
                    Details = new List<Dt_DeliveryOrderDetail>()
                };
                foreach (var item in dt_InventoryInfos)
                // æƒ…况1:大件库有散件,且用户输入数量小于等于散件总数,一次性调拨所有散件
                if (totalLooseQty > 0 && qty <= totalLooseQty)
                {
                    decimal taskQty = 0;
                    if (zx < 1) break;
                    while (item.AvailableQuantity > 0 && zx > 0)
                    decimal remainingLooseQty = totalLooseQty;
                    foreach (var item in dt_InventoryInfos)
                    {
                        zx--;
                        Qty += materielInfo.BoxQty;
                        taskQty += materielInfo.BoxQty;
                        materielInfo.Business_qty += materielInfo.BoxQty;
                        item.OutboundQuantity += materielInfo.BoxQty;
                        item.AvailableQuantity -= materielInfo.BoxQty;
                        if (remainingLooseQty <= 0) break;
                        var looseQty = item.AvailableQuantity % materielInfo.BoxQty;
                        if (looseQty > 0)
                        {
                            // ä¸€æ¬¡æ€§è°ƒæ‹¨è¯¥åº“存记录中的所有散件
                            item.OutboundQuantity += looseQty;
                            item.AvailableQuantity -= looseQty;
                            Qty += looseQty;
                            businessQtyToAdd += looseQty;
                            remainingLooseQty -= looseQty;
                            // æ·»åŠ ä¾›åº”ä»»åŠ¡
                            Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                            {
                                WarehouseCode = item.WarehouseCode,
                                BatchNo = item.BatchNo,
                                MaterielName = item.MaterielName,
                                MaterielCode = item.MaterielCode,
                                MaterielSpec = item.MaterielSpec,
                                TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                TaskType = TaskTypeEnum.AllocatOut.ObjToInt(),
                                CreateDate = DateTime.Now,
                                Creater = App.User.UserName ?? "System",
                                LocationCode = item.LocationCode,
                                OrderNo = deliveryOrder.Out_no,
                                Modifier= item.ValidityPeriod,//效期
                                StockQuantity = looseQty,
                                SupplyQuantity = 0,
                                Remark = "散件调拨出库(一次性清理)"
                            };
                            supplyTasks.Add(supplyTask);
                        }
                    }
                    #region æ·»åŠ è°ƒæ‹¨å‡ºåº“ä»»åŠ¡
                    Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                    {
                        WarehouseCode = item.WarehouseCode,
                        BatchNo = item.BatchNo,
                        MaterielName = item.MaterielName,
                        MaterielCode = item.MaterielCode,
                        MaterielSpec = item.MaterielSpec,
                        TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                        TaskType = TaskTypeEnum.AllocatOut.ObjToInt(),
                        CreateDate = DateTime.Now,
                        Creater = App.User.UserName ?? "System",
                        LocationCode = item.LocationCode,
                        OrderNo = deliveryOrder.Out_no,
                        StockQuantity = taskQty,
                        SupplyQuantity = 0,
                        Remark = "调拨出库"
                    };
                    supplyTasks.Add(supplyTask);
                    #endregion
                }
                // æƒ…况2:大件库有散件,但用户输入数量大于散件总数,或者大件库没有散件,按原来整箱逻辑
                else
                {
                    // å¦‚果大件库有散件但用户要调拨更多,先清理散件
                    decimal allocatedLooseQty = 0;
                    if (totalLooseQty > 0)
                    {
                        foreach (var item in dt_InventoryInfos)
                        {
                            var looseQty = item.AvailableQuantity % materielInfo.BoxQty;
                            if (looseQty > 0)
                            {
                                // ä¸€æ¬¡æ€§è°ƒæ‹¨è¯¥åº“存记录中的所有散件
                                item.OutboundQuantity += looseQty;
                                item.AvailableQuantity -= looseQty;
                                allocatedLooseQty += looseQty;
                                Qty += looseQty;
                                businessQtyToAdd += looseQty;
                                // æ·»åŠ ä¾›åº”ä»»åŠ¡
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    WarehouseCode = item.WarehouseCode,
                                    BatchNo = item.BatchNo,
                                    MaterielName = item.MaterielName,
                                    MaterielCode = item.MaterielCode,
                                    MaterielSpec = item.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = TaskTypeEnum.AllocatOut.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = item.LocationCode,
                                    OrderNo = deliveryOrder.Out_no,
                                    StockQuantity = looseQty,
                                    Modifier = item.ValidityPeriod,//效期
                                    SupplyQuantity = 0,
                                    Remark = "散件调拨出库(一次性清理)"
                                };
                                supplyTasks.Add(supplyTask);
                            }
                        }
                    }
                    // è®¡ç®—还需要调拨的整箱数量
                    var remainingQty = qty - allocatedLooseQty;
                    if (remainingQty > 0)
                    {
                        var zx = (int)Math.Ceiling((decimal)remainingQty / materielInfo.BoxQty); // éœ€è¦çš„æ•´ç®±æ•°
                        foreach (var item in dt_InventoryInfos)
                        {
                            decimal taskQty = 0;
                            if (zx < 1) break;
                            // è®¡ç®—当前库存可提供的完整箱数
                            var availableFullBoxes = item.AvailableQuantity / materielInfo.BoxQty;
                            var boxesToTransfer = Math.Min(availableFullBoxes, zx);
                            if (boxesToTransfer > 0)
                            {
                                var transferQty = boxesToTransfer * materielInfo.BoxQty;
                                taskQty += transferQty;
                                Qty += transferQty;
                                businessQtyToAdd += transferQty;
                                zx -= (int)boxesToTransfer;
                                item.OutboundQuantity += transferQty;
                                item.AvailableQuantity -= transferQty;
                                // æ·»åŠ ä¾›åº”ä»»åŠ¡
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    WarehouseCode = item.WarehouseCode,
                                    BatchNo = item.BatchNo,
                                    MaterielName = item.MaterielName,
                                    MaterielCode = item.MaterielCode,
                                    MaterielSpec = item.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = TaskTypeEnum.AllocatOut.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = item.LocationCode,
                                    OrderNo = deliveryOrder.Out_no,
                                    Modifier = item.ValidityPeriod,//效期
                                    StockQuantity = taskQty,
                                    SupplyQuantity = 0,
                                    Remark = "整箱调拨出库"
                                };
                                supplyTasks.Add(supplyTask);
                            }
                        }
                        // æ£€æŸ¥æ•´ç®±æ•°é‡æ˜¯å¦è¶³å¤Ÿ
                        if (zx > 0)
                        {
                            return WebResponseContent.Instance.Error($"整箱库存不足,无法完成调拨。还需要{zx}ç®±");
                        }
                    }
                }
                // æ›´æ–°ä¸šåŠ¡æ•°é‡ï¼šä¸šåŠ¡æ•°é‡ = åŽŸæ¥çš„ä¸šåŠ¡æ•°é‡ + å®žé™…调拨总数量
                materielInfo.Business_qty += businessQtyToAdd;
                // æ·»åŠ å‡ºåº“å•æ˜Žç»†
                Dt_DeliveryOrderDetail deliveryOrderDetail = new Dt_DeliveryOrderDetail()
                {
                    Batch_num = batchNo,
@@ -115,7 +373,8 @@
                    Reservoirarea = WareCode
                };
                deliveryOrder.Details.Add(deliveryOrderDetail);
                #region æ·»åŠ è°ƒæ‹¨å…¥åº“å•
                // æ·»åŠ è°ƒæ‹¨å…¥åº“å•
                Dt_CabinOrder cabinOrder = new Dt_CabinOrder()
                {
                    Order_no = deliveryOrder.Out_no,
@@ -137,7 +396,7 @@
                    };
                    cabinOrder.Details.Add(orderDetail);
                }
                #endregion
                Db.Ado.BeginTran();
                _materielInfoService.UpdateData(materielInfo);
                _inventoryInfoService.Repository.UpdateData(dt_InventoryInfos);
@@ -145,7 +404,8 @@
                if (deliveryOrder.Details.Count > 0) Db.InsertNav(deliveryOrder).Include(x => x.Details).ExecuteCommand();
                if (cabinOrder.Details.Count > 0) Db.InsertNav(cabinOrder).Include(x => x.Details).ExecuteCommand();
                Db.Ado.CommitTran();
                return WebResponseContent.Instance.OK("调拨出入库单生成成功,请操作调拨单");
                return WebResponseContent.Instance.OK($"调拨出入库单生成成功!实际调拨数量:{(int)Qty}");
            }
            catch (Exception ex)
            {
@@ -153,6 +413,9 @@
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        public WebResponseContent GetExpiredAndlow()
        {
            WebResponseContent content = new WebResponseContent();