using Admin.NET.Application.CommonHelper; using Admin.NET.Application.Entity; namespace Admin.NET.Application; /// /// 报检单服务 /// [ApiDescriptionSettings(ApplicationConst.WmsQCGroupName, Order = 100)] public class WmsOrderQcService : IDynamicApiController, ITransient { private readonly SqlSugarRepository _WmsBaseBusinessTypeRep; private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _wmsMaterialRep; private readonly SqlSugarRepository _WmsQcDetailsRep; private readonly SqlSugarRepository _BaseCustomerRep; private readonly SqlSugarRepository _WmsContainerMaterialRep; private readonly SqlSugarRepository _WmsQcTransRep; private readonly SqlSugarRepository _wmsLogActionRep; private readonly SqlSugarRepository _wmsRecordTransdRep; private readonly SqlSugarRepository _repSNRep; private readonly SqlSugarRepository _WmsNoCreateRuleRep; private readonly SqlSugarRepository _v_wms_stock_quanRep; private readonly SqlSugarRepository _wmsBaseBusinessType; private readonly SqlSugarRepository _wmsPlaceRep; public WmsOrderQcService( SqlSugarRepository WmsBaseBusinessTypeRep, SqlSugarRepository rep, SqlSugarRepository wmsMaterialRep, SqlSugarRepository wmsQcDetailsRep, SqlSugarRepository baseCustomerRep, SqlSugarRepository wmsContainerMaterialRep, SqlSugarRepository wmsQcTransRep, SqlSugarRepository wmsLogActionRep, SqlSugarRepository wmsRecordTransdRep, SqlSugarRepository repSNRep, SqlSugarRepository wmsNoCreateRuleRep, SqlSugarRepository v_wms_stock_quanRep, SqlSugarRepository wmsBaseBusinessType, SqlSugarRepository wmsPlaceRep ) { _WmsBaseBusinessTypeRep = WmsBaseBusinessTypeRep; _rep = rep; _wmsMaterialRep = wmsMaterialRep; _WmsQcDetailsRep = wmsQcDetailsRep; _BaseCustomerRep = baseCustomerRep; _WmsContainerMaterialRep = wmsContainerMaterialRep; _WmsQcTransRep = wmsQcTransRep; _wmsLogActionRep = wmsLogActionRep; _wmsRecordTransdRep = wmsRecordTransdRep; _repSNRep = repSNRep; _WmsNoCreateRuleRep = wmsNoCreateRuleRep; _v_wms_stock_quanRep = v_wms_stock_quanRep; _wmsBaseBusinessType = wmsBaseBusinessType; _wmsPlaceRep = wmsPlaceRep; } /// /// 分页查询报检单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Page")] [Description("WmsOrderQc/Page")] public async Task> Page(WmsOrderQcInput input) { var query = CommonPageFilter(input); return await query .OrderBy(x => x.QCOrderStatus).OrderByDescending(x => x.CreateTime) //.OrderBuilder(input) .ToPagedListAsync(input.Page, input.PageSize); } /// /// 不分页查询报检单 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "List")] [Description("WmsOrderQc/List")] public async Task> List([FromQuery] WmsOrderQcInput input) { var query = CommonPageFilter(input); //return await query.OrderBuilder(input, "", "u.Id").Select().ToListAsync(); return await query.OrderBuilder(input).Select().ToListAsync(); } /// /// 增加报检单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Add")] [Description("WmsOrderQc/Add")] public async Task Add(DiyAddWmsQcInput input) { //if (input.orderDetails is null || input.orderDetails.Count == 0) //{ // throw Oops.Oh("明细不能为空"); //} //var hearId = await AddOrderEFsql(input); return 200; } private async Task AddOrderEFsql(DiyAddWmsQcInput input) { //新增表头 var warehousOrder = input.Adapt(); var hearId = Yitter.IdGenerator.YitIdHelper.NextId(); warehousOrder.Id = hearId; // 获取当前时间 DateTime currentTime = DateTime.Now; // 格式化为年月日字符串 string formattedDate = currentTime.ToString("yyyyMMdd"); //按照单号规则生成单号 - 查找最新的创建的一条单据记录 var newestOrder = await _rep.AsQueryable().Where(p => p.RelationOrderType == OrderTypeEnum.报检单).Where(p => p.QCNo.Contains(formattedDate)).OrderBy(it => it.CreateTime, OrderByType.Desc) .FirstAsync(); //按照单号规则生成单号-ly warehousOrder.QCNo = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.报检单, _WmsNoCreateRuleRep, _repSNRep, (int)BusinessTypeEnum.进料检验, newestOrder == null ? null : newestOrder.QCNo); if (warehousOrder.QCNo == null || warehousOrder.QCNo == "") { warehousOrder.QCNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(); } warehousOrder.QCOrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); warehousOrder.BusinessTypeName = GetEnumDescriptionUtil.GetEnumDescription(BusinessTypeEnum.进料检验); //新增明细 var warehousOrderDetails1 = input.orderDetails.Adapt>(); int lineNumber = 0; foreach (var w in warehousOrderDetails1) { lineNumber++;//报检单行号实际可根据对接的第三方返回的格式定义。 w.QCLineNumber = lineNumber.ToString();//update by liuwq 20240526 w.GoodsQuantity = w.QCQuantity; var idMaterial = Yitter.IdGenerator.YitIdHelper.NextId(); w.Id = idMaterial; w.QCOrderId = warehousOrder.Id; w.RejectQuantity = w.QCQuantity - w.PassQuantity; w.QCOrderStatus = OrderStatusEnum.新建; w.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); w.QCOrderNo = warehousOrder.Id.ToString(); //w.RelationNo = ""; TODO 关联单号 update liuwq //w.RelationOrderType = null; TODO 关联单类型 update liuwq w.SNCode = "SN_" + w.Id.ToString(); if (w.QCQuantity == w.PassQuantity && w.PassQuantity > 0) { w.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.合格); } else if (w.QCQuantity != w.PassQuantity && w.PassQuantity > 0) { w.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.部分合格); } else if (w.QCQuantity == w.RejectQuantity) { w.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.不合格); } var Info_BaseCustomer = await _BaseCustomerRep.GetFirstAsync(u => u.CustCode == w.SupplierCode); if (Info_BaseCustomer != null) { w.SupplierName = Info_BaseCustomer.CustChinaName; } else { throw Oops.Oh("供应商编号不正确!"); } w.IsDelete = false; } try { await _rep.AsTenant().BeginTranAsync(); //插入主表 await _rep.InsertAsync(warehousOrder); //插入明细表 await _WmsQcDetailsRep.InsertRangeAsync(warehousOrderDetails1); await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } return hearId; } /// /// 删除报检单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Delete")] [Description("WmsOrderQc/Delete")] public async Task Delete(DeleteWmsQcInput input) { var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); //await _rep.FakeDeleteAsync(entity); //假删除 await _rep.DeleteAsync(entity); //真删除 } /// /// 更新报检单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Update")] [Description("WmsOrderQc/Update")] public async Task Update(UpdateWmsQcInput input) { var entity = input.Adapt(); //重复性验证 await CheckExist(entity, true); await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } /// /// 获取报检单 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "Detail")] [Description("WmsOrderQc/Detail")] public async Task Detail([FromQuery] QueryByIdWmsQcInput input) { return await _rep.GetFirstAsync(u => u.Id == input.Id); } /// /// 0708确认报检单:仅支持一次确认 仅处理一个单据 SNCode SNCode_1 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "ConfirmQc")] [Description("WmsOrderQc/ConfirmQc")] public async Task Confirm(DiyAddWmsQcInput input) { /// 1 验证输入明细不能为空; 订单是否不存在; 验证数量是否正确 ////2更新主表明细表 //// -- 2.1--主表-单据状态为【已完成】 //// -- 2.2--明细表-单据状态为【已完成】, 根据合格数更新质检状态为【合格|部分合格|不合格】 ////3操作库存表的物料 //// 3.1无需拆分物料 //// 3.1.1--全合格物料,更新【质检状态-合格】,更新【库存状态-待上架】,更新【库存数量】 //// 3.1.2--全不合格物料,更新【质检状态-不合格】,更新【库存状态-待上架】,更新【库存数量】 //// 3.2需要拆分的物料 //// 3.2.1--更新库存1条数据【合格物料】,更新【质检状态-合格】,更新【库存状态-待上架】,更新【库存数量】,更新【SNCode】 //// 3.2.2--增1条数据【不合格物料】,更新【质检状态-不合格】,更新【库存状态-待上架】,更新【库存数量】,更新【SNCode_1】 //// 3.2.3--删拆分之前的物料【SNCode】 // 4 添加更改库存记录 // 5更新操作履历 更新事务记录 if (input is null) { throw Oops.Oh("输入参不能为空"); } if (input.orderDetails is null || input.orderDetails.Count == 0) { throw Oops.Oh("明细不能为空"); } var dbOrder = await _rep.GetFirstAsync(w => w.QCNo == input.QCNo); if (dbOrder == null) { throw Oops.Oh($"订单{input.QCNo}不存在"); } //验证数量是否正确 foreach (var item in input.orderDetails) { if (item.QCQuantity != item.GoodsQuantity) { throw Oops.Oh($"物料{item.MaterialCode}的实检数量{item.QCQuantity}不等于收货数量{item.GoodsQuantity}"); } if (item.QCQuantity < item.PassQuantity) { throw Oops.Oh($"物料{item.MaterialCode}的实检数量{item.QCQuantity}不能小于合格数量{item.PassQuantity}"); } if (item.QCQuantity < item.RejectQuantity) { throw Oops.Oh($"物料{item.MaterialCode}的实检数量{item.QCQuantity}不能小于不合格数量{item.RejectQuantity}"); } if (item.QCQuantity != (item.RejectQuantity + item.PassQuantity)) { throw Oops.Oh($"物料{item.MaterialCode}的实检数量{item.QCQuantity}不能等于合格数量{item.PassQuantity}和不合格数量{item.RejectQuantity}之和"); } } var OrderDetails = await _WmsQcDetailsRep.AsQueryable() .Where(x => x.QCOrderId == dbOrder.Id) .Where(u => u.IsDelete == false) .Select() .ToListAsync(); List updateWareOrderDetails = new List(); List updateWmsContainerMaterial = new List(); List addWmsContainerMaterial = new List(); List deleteWmsContainerMaterial = new List(); List addWmsQcTrans = new List(); //新增事务记录 List addWmsRecordTransList = new List(); //寻找更新单据明细的物料 var updateList = OrderDetails.Where(x => input.orderDetails.Any(p => p.Id == x.Id && p.MaterialCode == x.MaterialCode)).ToList(); //寻找更新库存的物料 List queryCodeList = input.orderDetails.Select(v => v.SNCode).Distinct().ToList(); var handleList = await _WmsContainerMaterialRep.GetListAsync(u => queryCodeList.Contains(u.SNCode) && u.IsDelete == false); var snCodeList = handleList.Select(s => s.SNCode).ToList(); //获取要报检的库存视图-根据盘点库区的容器和盘点范围的物料获取盘点库存-包含库位信息、库区信息,新增事务用 var all_v_wms_stock_quanList = await _v_wms_stock_quanRep.GetListAsync(x => x.IsDelete == false && snCodeList.Contains(x.SNCode)); //获取库位相信 var placeCodeList = all_v_wms_stock_quanList.Select(s=>s.PlaceCode).Distinct().ToList(); var allPlaeList= await _wmsPlaceRep.GetListAsync(u=> placeCodeList.Contains(u.PlaceCode)&&u.IsDelete==false); //获取业务类型 BusinessTypeEnum businessTypeEnum = BusinessTypeEnum.报检; var businessTypeInfo = BusinessTypeHelper.GetBusinessTypeInfoFromDB((int)businessTypeEnum, _wmsBaseBusinessType); if (handleList == null || handleList.Count <= 0) { throw Oops.Oh($"没有找到需要更新的库存物料!"); } //2更新主表明细表 单据状态为【已完成】 质检状态为【合格|部分合格|不合格】 foreach (var item in updateList) { if (item.QCStatus == QcStatusEnum.待检) { throw Oops.Oh("待检状态不能操作!"); } var orderDetails = input.orderDetails.Where(x => x.MaterialCode == item.MaterialCode && x.Id == item.Id).First(); if (orderDetails == null) { continue; } else { //item.PassQuantity = (decimal)orderDetails.PassQuantity; //item.RejectQuantity = (decimal)orderDetails.QCQuantity - (decimal)orderDetails.PassQuantity; if (orderDetails.QCQuantity == orderDetails.PassQuantity) { item.QCStatus = QcStatusEnum.合格; item.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.合格); } if (orderDetails.PassQuantity > 0 && orderDetails.QCQuantity > orderDetails.PassQuantity) { item.QCStatus = QcStatusEnum.部分合格; item.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.部分合格); } if (orderDetails.QCQuantity == orderDetails.RejectQuantity) { item.QCStatus = QcStatusEnum.不合格; item.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.不合格); } item.QCOrderStatus = OrderStatusEnum.已完成; item.QCOrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已完成); } //变更明细的状态 updateWareOrderDetails.Add(item); } //2更改主表-单据状态-----------调用刘文奇的公共方法 OrderHelper.UpdateQCOrderStatus(OrderDetails, dbOrder); // dbOrder.QCOrderStatus = OrderStatusEnum.Completed; //3库存物料 foreach (var itemUp in handleList) { //获取源库存信息 var sourceStockView = StockQuanHelper.GetVMmsStockQuan(all_v_wms_stock_quanList, itemUp.SNCode); //获取目标库位信息 //目标库存不变 新增的库存也是源库存的库位 var toPlaceInfo = BaseInfoHelper.GetPlace(sourceStockView.PlaceCode, allPlaeList); //事务记录其他入参 TransferOtherDetail transferOtherDetail = new TransferOtherDetail() { RelationNo = dbOrder.QCNo,//报检单号 RelationNoLineNumber = string.Empty, Remarks = "", }; var orderDetails = input.orderDetails.Where(x => x.MaterialCode == itemUp.MaterialCode && x.SNCode == itemUp.SNCode).First(); if (orderDetails == null) { continue; } else { //4------------加拆分物料记录 var itemChifenOne = itemUp.Adapt(); itemChifenOne.QCOrderNo = dbOrder.QCNo; itemChifenOne.QCOrderDetailsId = orderDetails.Id; itemChifenOne.SNCode = itemUp.SNCode; //3.1无需拆分物料 实检 = 合格数 if (orderDetails.QCQuantity == orderDetails.PassQuantity) { //实检 = 合格数 itemUp.QCStatus = StockQcStatusEnum.合格; itemUp.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(StockQcStatusEnum.合格); StockQuanHelper.UpdateStockStatus(itemUp, StockStatusEnum.待上架, BusinessTypeEnum.报检.GetDescription()); itemUp.Quantity = (decimal)orderDetails.QCQuantity; //4------------加拆分物料记录 itemChifenOne.Id = Yitter.IdGenerator.YitIdHelper.NextId(); itemChifenOne.PassQuantity = (decimal)orderDetails.QCQuantity; addWmsQcTrans.Add(itemChifenOne); updateWmsContainerMaterial.Add(itemUp); //更新库存表 //库存状态、质检状态变更 创建事务记录 update by liuwq 20240730 addWmsRecordTransList.Add(LogRecordHelper.CreateWmsRecordTrans(businessTypeInfo, sourceStockView, itemUp, toPlaceInfo, transferOtherDetail)); } //3.1无需拆分物料 实检 = 不合格数 if (orderDetails.QCQuantity == orderDetails.RejectQuantity) { //实检 = 不合格数 itemUp.QCStatus = StockQcStatusEnum.不合格; itemUp.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(StockQcStatusEnum.不合格); StockQuanHelper.UpdateStockStatus(itemUp, StockStatusEnum.待上架, BusinessTypeEnum.报检.GetDescription()); itemUp.Quantity = (decimal)orderDetails.QCQuantity; //4------------加拆分物料记录 itemChifenOne.Id = Yitter.IdGenerator.YitIdHelper.NextId(); itemChifenOne.RejectQuantity = (decimal)orderDetails.QCQuantity; addWmsQcTrans.Add(itemChifenOne); updateWmsContainerMaterial.Add(itemUp); //更新库存表 //库存状态、质检状态变更 创建事务记录 update by liuwq 20240730 addWmsRecordTransList.Add(LogRecordHelper.CreateWmsRecordTrans(businessTypeInfo, sourceStockView, itemUp, toPlaceInfo, transferOtherDetail)); } //3.2需要拆分的物料 实检 > 合格数 if (orderDetails.PassQuantity > 0 && orderDetails.QCQuantity > orderDetails.PassQuantity) { //------------A-更新合格1条 itemUp.QCStatus = StockQcStatusEnum.合格; itemUp.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(StockQcStatusEnum.合格); StockQuanHelper.UpdateStockStatus(itemUp, StockStatusEnum.待上架, BusinessTypeEnum.报检.GetDescription()); itemUp.Quantity = (decimal)orderDetails.PassQuantity; updateWmsContainerMaterial.Add(itemUp); //更新库存表 //库存状态、质检状态、数量变更 创建事务记录 update by liuwq 20240730 addWmsRecordTransList.Add(LogRecordHelper.CreateWmsRecordTrans(businessTypeInfo, sourceStockView, itemUp, toPlaceInfo, transferOtherDetail)); //---------------------B-加不合格1条----------------- var itemReject = itemUp.Adapt(); itemReject.Id = Yitter.IdGenerator.YitIdHelper.NextId(); itemReject.QCStatus = StockQcStatusEnum.不合格; itemReject.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(StockQcStatusEnum.不合格); StockQuanHelper.UpdateStockStatus(itemReject, StockStatusEnum.待上架, BusinessTypeEnum.报检.GetDescription()); itemReject.Quantity = (decimal)orderDetails.RejectQuantity; itemReject.SourceSNCode = itemReject.SNCode;//记录源跟踪码 update by liuwq 20240719 itemReject.SNCode = itemReject.SNCode + "_1"; addWmsContainerMaterial.Add(itemReject); //新增状态、质检状态 数量 创建事务记录 update by liuwq 20240730 //新增的库存源信息都是空 addWmsRecordTransList.Add(LogRecordHelper.CreateWmsRecordTrans(businessTypeInfo, null, itemReject, toPlaceInfo, transferOtherDetail)); //4------------加拆分物料记录 对应A-加合格1条 itemChifenOne.SNCode = itemUp.SNCode; itemChifenOne.Id = Yitter.IdGenerator.YitIdHelper.NextId(); itemChifenOne.PassQuantity = itemUp.Quantity; addWmsQcTrans.Add(itemChifenOne); //4------------加拆分物料记录 对应B-加不合格1条- var itemChifenReject = itemUp.Adapt(); itemChifenReject.QCOrderNo = dbOrder.QCNo; itemChifenReject.QCOrderDetailsId = orderDetails.Id; itemChifenReject.SNCode = itemReject.SNCode; itemChifenReject.Id = Yitter.IdGenerator.YitIdHelper.NextId(); itemChifenReject.RejectQuantity = itemReject.Quantity; addWmsQcTrans.Add(itemChifenReject); //----------3.3删除之前的数据1条 //deleteWmsContainerMaterial.Add(itemUp); } } } //添加操作履历操作日志 update by liuwq 20240720 List addWmsLogActionList = new List(); WmsLogAction wmsLogAction = LogActionHelper.CreateWmsLogAction(dbOrder.Id, $"报检单{dbOrder.QCNo}{BusinessTypeEnum.报检.GetDescription()}"); addWmsLogActionList.Add(wmsLogAction); try { await _rep.AsTenant().BeginTranAsync(); if (updateWareOrderDetails.Count > 0) { await _rep.UpdateAsync(dbOrder); //更新主表 await _WmsQcDetailsRep.UpdateRangeAsync(updateWareOrderDetails); //更新明细表 if (updateWmsContainerMaterial.Count > 0) { await _WmsContainerMaterialRep.UpdateRangeAsync(updateWmsContainerMaterial); //更新库存表-3.1无需拆分物料 } //if (deleteWmsContainerMaterial.Count > 0) //{ // await _WmsContainerMaterialRep.DeleteAsync(deleteWmsContainerMaterial); //删除库存表 -3.2需要拆分的物料 //} if (addWmsContainerMaterial.Count > 0) { await _WmsContainerMaterialRep.InsertRangeAsync(addWmsContainerMaterial); //插上架存表 -3.2需要拆分的物料 ---拆分不合格 A_1 } if (addWmsQcTrans.Count > 0) { await _WmsQcTransRep.InsertRangeAsync(addWmsQcTrans); //插入更改库存记录 } //// 4新增操作履历操作日志 update by liuwq 20240720 await _wmsLogActionRep.InsertRangeAsync(addWmsLogActionList); // 5新增事务记录 update by liuwq 20240720 await _wmsRecordTransdRep.InsertRangeAsync(addWmsRecordTransList); } await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } } /// /// 获取拆分物料明细 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "WmsOrderQcTransDetail")] [Description("WmsOrderQc/WmsOrderQcTransDetail")] public async Task> SplitMaterialDetail([FromQuery] QuerySplitMaterialDetailInput input) { var query = _WmsQcTransRep.AsQueryable() .WhereIF(input.QCOrderDetailsId > 0, u => u.QCOrderDetailsId == input.QCOrderDetailsId) .Select(); return await query.Select().Distinct().ToListAsync(); } /// /// WMS系统-手工确认质检:仅支持一次确认 仅处理一个单据 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "HandleConfirmQc")] [Description("WmsOrderQc/HandleConfirmQc")] public async Task HandleConfirmQc(DiyAddWmsQcInput input) { if (input is null) { throw Oops.Oh("输入参不能为空"); } if (input.orderDetails is null || input.orderDetails.Count == 0) { throw Oops.Oh("明细不能为空"); } var dbOrder = await _rep.GetFirstAsync(w => w.QCNo == input.QCNo); if (dbOrder == null) { throw Oops.Oh($"订单{input.QCNo}不存在"); } //验证数量是否正确 foreach (var item in input.orderDetails) { if (item.PassQuantity == 0 && item.RejectQuantity == 0) { throw Oops.Oh($"物料{item.MaterialCode}的合格数量和不合格数量必须大于0"); } if (item.PassQuantity < 0) { throw Oops.Oh($"物料{item.MaterialCode}的合格数量必须大于0"); } if (item.RejectQuantity < 0) { throw Oops.Oh($"物料{item.MaterialCode}的不合格数量必须大于0"); } if (item.GoodsQuantity <= 0) { throw Oops.Oh($"物料{item.MaterialCode}的已收数量{item.GoodsQuantity}必须大于0"); } decimal dQty = ((decimal)item.RejectQuantity + (decimal)item.PassQuantity); decimal dQtyT = Convert.ToDecimal(item.GoodsQuantity); if (dQtyT != dQty) { throw Oops.Oh($"物料{item.MaterialCode}的已收数量{item.GoodsQuantity}必须等于合格数量{item.PassQuantity}和不合格数量{item.RejectQuantity}之和"); } } var OrderDetails = await _WmsQcDetailsRep.AsQueryable() .Where(x => x.QCOrderId == dbOrder.Id) .Where(u => u.QCStatus == QcStatusEnum.待检) .Where(u => u.IsDelete == false) .Select() .ToListAsync(); List updateWareOrderDetails = new List(); List updateWmsContainerMaterial = new List(); //寻找更新单据明细的物料 var updateList = OrderDetails.Where(x => input.orderDetails.Any(p => p.Id == x.Id && p.MaterialCode == x.MaterialCode)).ToList(); if (updateList == null || updateList.Count <= 0) { throw Oops.Oh($"质检物料信息传入错误!"); } //寻找更新库存的物料 List queryCodeList = input.orderDetails.Select(v => v.SNCode).Distinct().ToList(); var handleList = await _WmsContainerMaterialRep.GetListAsync(u => queryCodeList.Contains(u.SNCode) && u.IsDelete == false); if (handleList == null || handleList.Count <= 0) { throw Oops.Oh($"没有找到需要更新的库存物料!"); } //2更新主表明细表 单据状态为【执行中】 质检状态为【合格|部分合格|不合格】 foreach (var item in updateList) { if (item.QCStatus != QcStatusEnum.待检) { throw Oops.Oh("质检状态不是待检!"); } var orderDetails = input.orderDetails.Where(x => x.MaterialCode == item.MaterialCode && x.Id == item.Id).First(); if (orderDetails == null) { continue; } else { item.QCQuantity = (decimal)orderDetails.GoodsQuantity; item.PassQuantity = (decimal)orderDetails.PassQuantity; item.RejectQuantity = (decimal)orderDetails.GoodsQuantity - (decimal)orderDetails.PassQuantity; if (orderDetails.GoodsQuantity == orderDetails.PassQuantity) { item.QCStatus = QcStatusEnum.合格; item.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.合格); } else if (orderDetails.GoodsQuantity == orderDetails.RejectQuantity) { item.QCStatus = QcStatusEnum.不合格; item.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.不合格); } else { item.QCStatus = QcStatusEnum.部分合格; item.QCStatusName = GetEnumDescriptionUtil.GetEnumDescription(QcStatusEnum.部分合格); } item.QCOrderStatus = OrderStatusEnum.处理中; item.QCOrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.处理中); } //变更明细的状态 updateWareOrderDetails.Add(item); } //2更改主表-单据状态-----------调用的公共方法 OrderHelper.UpdateQCOrderStatus(OrderDetails, dbOrder); //3库存物料 foreach (var itemUp in handleList) { var orderDetails = input.orderDetails.Where(x => x.MaterialCode == itemUp.MaterialCode && x.SNCode == itemUp.SNCode).First(); if (orderDetails == null) { continue; } else { if (itemUp.StockStatus != StockStatusEnum.待质检) { throw Oops.Oh($"物料{itemUp.MaterialCode}的状态不是待质检!"); } StockQuanHelper.UpdateStockStatus(itemUp, StockStatusEnum.待上架, BusinessTypeEnum.报检.GetDescription()); } updateWmsContainerMaterial.Add(itemUp); } try { await _rep.AsTenant().BeginTranAsync(); if (updateWareOrderDetails.Count > 0) { await _rep.UpdateAsync(dbOrder); //更新主表 await _WmsQcDetailsRep.UpdateRangeAsync(updateWareOrderDetails); //更新明细表 if (updateWmsContainerMaterial.Count > 0) { await _WmsContainerMaterialRep.UpdateRangeAsync(updateWmsContainerMaterial); //更新库存表 - 待上架 } // 4更新操作履历 // 5更新事务记录 } await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } } #region 私有方法 /// /// 公共查询报检单条件 /// /// /// private ISugarQueryable CommonPageFilter(WmsOrderQcInput input) { var query = _rep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.QCNo.Contains(input.SearchKey.Trim()) || u.QCOrderStatusName.Contains(input.SearchKey.Trim()) || u.SupplierName.Contains(input.SearchKey.Trim()) || u.SupplierCode.Contains(input.SearchKey.Trim()) || u.CustCode.Contains(input.SearchKey.Trim()) || u.CustChinaName.Contains(input.SearchKey.Trim()) || u.CustEnglishName.Contains(input.SearchKey.Trim()) || u.RelationNo.Contains(input.SearchKey.Trim()) || u.RelationOrderTypeName.Contains(input.SearchKey.Trim()) || u.Remarks.Contains(input.SearchKey.Trim()) || u.ErpVoucher.Contains(input.SearchKey.Trim()) || u.CreateUserName.Contains(input.SearchKey.Trim()) || u.UpdateUserName.Contains(input.SearchKey.Trim()) ) .WhereIF(!string.IsNullOrWhiteSpace(input.QCNo), u => u.QCNo.Contains(input.QCNo.Trim())) .WhereIF(input.BusinessType.HasValue, u => u.BusinessType == input.BusinessType) .WhereIF(input.QCOrderStatus.HasValue, u => u.QCOrderStatus == input.QCOrderStatus) .WhereIF(!string.IsNullOrWhiteSpace(input.SupplierName), u => u.SupplierName.Contains(input.SupplierName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.SupplierCode), u => u.SupplierCode.Contains(input.SupplierCode.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.CustCode), u => u.CustCode.Contains(input.CustCode.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.CustChinaName), u => u.CustChinaName.Contains(input.CustChinaName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.CustEnglishName), u => u.CustEnglishName.Contains(input.CustEnglishName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.RelationNo), u => u.RelationNo.Contains(input.RelationNo.Trim())) .WhereIF(input.RelationOrderType.HasValue, u => u.RelationOrderType == input.RelationOrderType) .WhereIF(!string.IsNullOrWhiteSpace(input.Remarks), u => u.Remarks.Contains(input.Remarks.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.ErpVoucher), u => u.ErpVoucher.Contains(input.ErpVoucher.Trim())) .Select(); return query; } /// /// 重复性验证 /// /// 验证对象 /// 是否是编辑 /// private async Task CheckExist(WmsOrderQc input, bool isEdit = false) { //没有配置组合校验,不需要验重 //没有配置单独校验,不需要验重 } #endregion }