using NewPdaSqlServer.DB; using NewPdaSqlServer.Dto.service; using NewPdaSqlServer.entity; using NewPdaSqlServer.util; using SqlSugar; namespace NewPdaSqlServer.service.Warehouse; /// /// 调拨出库管理类 /// 负责处理调拨出库相关的业务逻辑 /// public class TransferOutManager : Repository { /// /// 获取未完成的调拨出库单号列表 /// /// 未完成的调拨出库单号列表 public List GetTransferOutNoList() { // 先从数据库获取Transfer_Out_ETAIL表的数据 var transferOutDetails = Db.Queryable().ToList(); // 使用LINQ对获取的数据进行分组和筛选 // 筛选条件:申请数量(sq)不等于已扫数量(ys)的记录 var result = transferOutDetails .GroupBy(x => x.Pid) .Select(g => new { pid = g.Key, sq = g.Sum(x => x.ShNum), // 申请数量合计 ys = g.Sum(x => x.YsNum) // 已扫数量合计 }) .Where(x => (x.sq ?? 0) != (x.ys ?? 0)) .Select(x => x.pid) .ToList(); // 根据pid查询对应的出库单号 var billNos = Db.Queryable() .Where(x => result.Contains(x.Guid)) .Select(x => x.BillNo) .ToList(); return billNos; } /// /// 根据单据号获取待处理的调拨出库明细列表 /// /// 查询参数,包含单据号 /// 待处理的调拨出库明细列表 public List GetTransferOutDetailListByBillNo( WarehouseQuery query) { var p_bill_no = query.billNo; // 根据SQL查询条件获取待处理的出库明细 // 关联查询TransferOutDetail、TransferOut和MesItems三张表 // 筛选条件:未完成数量大于0且单据已审核 var result = Db.Queryable( (b, a, s) => new JoinQueryInfos( JoinType.Left, b.Pid == a.Guid, JoinType.Left, b.ItemId == s.Id)) .Where((b, a, s) => (b.ShNum ?? 0) - (b.YsNum ?? 0) > 0 // 未完成数量大于0 && a.BillNo == p_bill_no // 匹配单据号 && a.Status == 1) // 单据已审核 .OrderBy((b, a, s) => s.ItemNo) .Select((b, a, s) => new TransferOutDetail { ItemNo = s.ItemNo, ItemModel = s.ItemModel, ShNum = b.ShNum, // 申请数量 YsNum = b.YsNum, // 已扫数量 // 保留其他必要字段... Pid = b.Pid, ItemId = b.ItemId, Guid = b.Guid }) .ToList(); return result; } /// /// 扫描条码进行调拨出库处理 /// /// 包含单据号、用户名和条码信息的查询参数 /// 处理后的表单和待处理明细列表 public (WarehouseQuery form, List items) ScanMoveBarcode(WarehouseQuery query) { var p_bill_no = query.billNo; var c_user = query.userName; var p_item_barcode = query.barcode; var p_bill_type_id = 300; // 单据类型ID var p_transaction_no = 301; // 交易编号 // 验证单据号 if (string.IsNullOrEmpty(p_bill_no)) { throw new Exception("请选取单据号!"); } // 查询出库单并验证状态 var transferOut = Db.Queryable() .Where(x => x.BillNo == p_bill_no && x.Status == 1) .First(); if (transferOut == null) { throw new Exception("未找到调拨申请单或者调拨申请单没审核"); } // 查询条码库存信息并验证 var stock = Db.Queryable() .Where(x => x.ItemBarcode == p_item_barcode && x.Quantity > 0 && !string.IsNullOrEmpty(x.DepotsCode)) .First(); if (stock == null) { throw new Exception($"库存中无此条码,请核对!{p_item_barcode}"); } // 验证仓库一致性 if (stock.DepotsCode != transferOut.InvCode) { throw new Exception( $"条码库存仓库{stock.DepotsCode}和申请仓库不一致{transferOut.InvCode}"); } // 查询物料信息 var item = Db.Queryable() .Where(x => x.Id == stock.ItemId) .First(); if (item == null) { throw new Exception("未找到物料"); } // 查询调拨明细并验证 var detail = Db.Queryable() .Where(x => x.ItemId == stock.ItemId && x.Pid == transferOut.Guid) .First(); if (detail == null) { throw new Exception("未找到条码物料相应的调拨申请"); } // 验证数量是否超出未扫数量 if ((detail.ShNum ?? 0) - (detail.YsNum ?? 0) < stock.Quantity) { throw new Exception("条码数量大于申请未扫数量,请拆分了再扫码"); } // 使用事务处理数据更新 UseTransaction(db => { // 查询现有移库记录 var existingMove = db.Queryable() .Where(x => x.TaskNo == p_bill_no && x.TransactionNo == p_transaction_no && (x.Status ?? 0) == 0) .First(); var commit = 0; // 记录更新操作次数 var c_id = Guid.Empty; // 处理移库主表记录 if (existingMove != null) { // 更新现有记录的最后修改信息 commit += db.Updateable() .SetColumns(s => s.LastupdateDate == DateTime.Now) .SetColumns(s => s.LastupdateBy == c_user) .Where(s => s.Guid == existingMove.Guid) .ExecuteCommand(); c_id = existingMove.Guid; } else { // 查询相关仓库信息 var mesDepots = db.Queryable() .Where(s => s.DepotCode == transferOut.FromCode) .First(); var invMesDepots = db.Queryable() .Where(s => s.DepotCode == transferOut.InvCode) .First(); c_id = Guid.NewGuid(); // 创建新的移库记录 var newMove = new MesInvItemMoves { Guid = c_id, BillNo = BillNo.GetBillNo("DBCKD"), CreateBy = c_user, CreateDate = DateTime.Now, BillTypeId = p_bill_type_id, TransactionNo = p_transaction_no, InvDepotSectionsId = mesDepots.DepotId, // InvDepotSectionsCode = transferOut.FromCode, // FromDepotsCode = transferOut.InvCode, FromDepotsId = invMesDepots.DepotId.ToString(), TaskNo = p_bill_no }; commit += db.Insertable(newMove).IgnoreColumns(true) .ExecuteCommand(); } // 写入老条码交易明细 var business = new MesInvBusiness2 { Guid = Guid.NewGuid(), Status = 1, BillTypeId = p_bill_type_id, TransactionCode = p_transaction_no.ToString(), BusinessType = -1, ItemBarcode = p_item_barcode, ItemNo = item.ItemNo, LotNo = stock.LotNo, EpFlag = true, Quantity = stock.Quantity, FromInvDepotsCode = stock.DepotsCode, FromInvDepotSectionsCode = stock.DepotSectionsCode, ToInvDepotsCode = transferOut.FromCode, ToInvDepotSectionsCode = stock.DepotSectionsCode, CreateBy = c_user, CreateDate = DateTime.Now, LastupdateBy = c_user, LastupdateDate = DateTime.Now, Factory = stock.Factory, Company = stock.Company, TaskNo = stock.TaskNo, BillNo = p_bill_no, WorkNo = stock.WorkNo, WorkLine = stock.WorkLine, SuppNo = stock.SuppNo, ItemId = stock.ItemId, EbelnK3id = stock.EbelnK3id, LineK3id = stock.LineK3id, // RkDepot = transferOut.RkDepot, // CkDepot = transferOut.CkDepot }; commit += db.Insertable(business).IgnoreColumns(true) .ExecuteCommand(); // 写入新条码交易明细 var moveDetail = new MesInvItemMovesCDetails { Guid = Guid.NewGuid(), ItemMoveGuid = c_id, ItemBarcode = p_item_barcode, CItemCode = stock.CItemCode, ItemNo = item.ItemNo, LotNo = stock.LotNo, Quantity = stock.Quantity, EpFlag = stock.EpFlag, CreateBy = c_user, CreateDate = DateTime.Now, LastupdateBy = c_user, LastupdateDate = DateTime.Now, // CustomerNo = stock.CustomerNo, TaskNo = stock.TaskNo, FromDepotsCode = stock.DepotsCode, FromDepotSectionsCode = stock.DepotSectionsCode, Factory = stock.Factory, Company = stock.Company, InvDepotsCode = transferOut.FromCode, // InvDepotSectionsCode = p_sectioncode, IqcStatus = stock.IqcStatus, Fcar = stock.Fcar, IndepDate = stock.IndepDate, VisableSubmit = stock.VisableSubmit, VisableSubmitBy = stock.VisableSubmitBy, VisableSubmitDate = stock.VisableSubmitDate, BoardStyle = stock.BoardStyle, WorkNo = stock.WorkNo, WorkLine = stock.WorkLine, SuppNo = stock.SuppNo, ItemId = (int)stock.ItemId, EbelnK3id = stock.EbelnK3id, LineK3id = stock.LineK3id, // RkDepot = transferOut.RkDepot, // CkDepot = transferOut.CkDepot }; commit += db.Insertable(moveDetail).IgnoreColumns(true) .ExecuteCommand(); // 更新或插入出库明细记录 var outItem = db.Queryable() .Where(x => x.ItemOutId == c_id && x.ItemId == stock.ItemId) .First(); if (outItem != null) { // 更新现有记录的数量 outItem.Quantity += stock.Quantity; commit += db.Updateable() .SetColumns(x => x.Quantity == outItem.Quantity) .Where(x => x.Guid == outItem.Guid) .ExecuteCommand(); } else { // 插入新记录 var newOutItem = new MesInvItemOutItems { Guid = Guid.NewGuid(), ItemOutId = c_id, ItemId = stock.ItemId, CreateBy = c_user, CreateDate = DateTime.Now, TaskNo = stock.TaskNo, WorkNo = stock.WorkNo, WorkLine = stock.WorkLine, EbelnK3id = (int)stock.EbelnK3id, LineK3id = (int)stock.LineK3id, Quantity = stock.Quantity, // Unit = stock.ItemUnit }; commit += db.Insertable(newOutItem).IgnoreColumns(true) .ExecuteCommand(); } // 更新调拨申请已扫数量 detail = db.Queryable() .Where(x => x.Guid == detail.Guid) .First(); if (detail != null) { detail.YsNum = (detail.YsNum ?? 0) + stock.Quantity as int?; commit += db.Updateable() .SetColumns(x => x.YsNum == detail.YsNum) .Where(x => x.Guid == detail.Guid) .ExecuteCommand(); } // 检查是否所有明细都已完成 var totals = db.Queryable((b, a) => new JoinQueryInfos(JoinType.Left, b.Pid == a.Guid)) .Where((b, a) => a.BillNo == p_bill_no) .Select((b, a) => new { ShNum = SqlFunc.AggregateSum(b.ShNum), // 申请总数量 YsNum = SqlFunc.AggregateSum(b.YsNum) // 已扫总数量 }) .First(); // 如果申请数量等于已扫数量,更新单据完成状态 if (totals.ShNum == totals.YsNum) { commit += db.Updateable() .SetColumns(x => x.IsWc == 1) .Where(x => x.BillNo == p_bill_no) .ExecuteCommand(); } // 更新返回参数 query.itemNo = item.ItemNo; query.Num = stock.Quantity; // 验证更新操作是否全部成功 if (commit < 4) { throw new Exception("更新失败"); } return commit; }); // 返回更新后的表单和待处理明细 return (query, GetTransferOutDetailListByBillNo(query)); } }