using AutoMapper; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.CommonEnum; using WIDESEA_Common.OrderEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.CodeConfigEnum; using WIDESEA_Core.Helper; using WIDESEA_DTO; using WIDESEA_DTO.Basic; using WIDESEA_DTO.QMS; using WIDESEA_External.Model; using WIDESEA_External.QMSService; using WIDESEA_IBasicRepository; using WIDESEA_ICheckRepository; using WIDESEA_IInboundRepository; using WIDESEA_IInboundService; using WIDESEA_IStockRepository; using WIDESEA_Model.Models; namespace WIDESEA_InboundService { public class ReceiveOrderDetailService : ServiceBase, IReceiveOrderDetailService { private readonly IMapper _mapper; private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IInboundRepository _inboundRepository; private readonly IBasicRepository _basicRepository; private readonly ICheckOrderRepository _checkOrderRepository; private readonly IStockRepository _stockRepository; private readonly ISupplierInfoRepository _supplierInfoRepository; private readonly IInvokeQMSService _invokeQMSService; public ReceiveOrderDetailService(IReceiveOrderDetailRepository BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IInboundRepository inboundRepository, IBasicRepository basicRepository, ICheckOrderRepository checkOrderRepository, IStockRepository stockRepository,ISupplierInfoRepository supplierInfoRepository,IInvokeQMSService invokeQMSService) : base(BaseDal) { _mapper = mapper; _unitOfWorkManage = unitOfWorkManage; _inboundRepository = inboundRepository; _basicRepository = basicRepository; _checkOrderRepository = checkOrderRepository; _stockRepository = stockRepository; _supplierInfoRepository = supplierInfoRepository; _invokeQMSService = invokeQMSService; } private static object _rowNoLocker = new object(); /// /// 扫码添加收货单明细(单个) /// /// 物料码 /// 收货单号 /// public WebResponseContent AddReceiveOrderDetail(string serNum, string orderNo) { try { Dt_ReceiveOrder receiveOrder = _inboundRepository.ReceiveOrderRepository.Db.Queryable().Where(x => x.ReceiveOrderNo == orderNo).Includes(x => x.Details).First(); if (receiveOrder == null) { return WebResponseContent.Instance.Error($"未找到该收货单"); } if (receiveOrder.ReceiveOrderStatus == ReceiveOrderStatusEnum.Completed.ObjToInt()) { return WebResponseContent.Instance.Error($"该单据已收货完成"); } Dt_Warehouse warehouse = _basicRepository.WarehouseRepository.QueryFirst(x => x.WarehouseId == receiveOrder.WarehouseId); MatSerNumAnalysisModel model = CodeAnalysisHelper.CodeAnalysis(AnalysisCodeEnum.MatSerNumAnalysis, serNum); Dt_SupplierInfo supplierInfo = _supplierInfoRepository.QueryFirst(x => x.SupplierCode == receiveOrder.SuppliersId); //收货增加批次卡控 //查询收货明细是否有存在同一个批次 Dt_ReceiveOrderDetail receiveOrderDetailOld = _inboundRepository.ReceiveOrderDetailRepository.QueryFirst(x => x.LotNo == model.LotNo && x.MaterielCode == model.MaterielCode); Dt_ReceiveOrder? receiveOrderOld = null; if (receiveOrderDetailOld!=null) { receiveOrderOld = _inboundRepository.ReceiveOrderRepository.QueryFirst(x => x.ReceiveOrderId == receiveOrderDetailOld.ReceiveOrderId); } if (receiveOrderDetailOld!=null && receiveOrderOld?.WarehouseId== receiveOrder.WarehouseId) { return WebResponseContent.Instance.Error($"收货单号{receiveOrderOld.ReceiveOrderNo}中批次{model.LotNo}已存在"); } //查询库存批次是否有存在同一个批次 Dt_StockInfoDetail stockInfoDetail = _stockRepository.StockInfoDetailRepository.QueryFirst(x => x.BatchNo == model.LotNo && x.MaterielCode == model.MaterielCode); Dt_StockInfo? stockInfo = null; if (stockInfoDetail!=null) { stockInfo = _stockRepository.StockInfoRepository.QueryFirst(x => x.Id == stockInfoDetail.Id); } if (stockInfoDetail!=null && stockInfo?.WarehouseId==receiveOrder.WarehouseId) { return WebResponseContent.Instance.Error($"库存{stockInfo.PalletCode}中批次{model.LotNo}已存在"); } if (model!=null) { string format = "yyyy-MM-dd"; // 目标格式 DateTime parsedDate; // 解析验证格式 bool isValidEffDate = DateTime.TryParseExact( model.EffectiveDate, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate ); bool isValidProDate = DateTime.TryParseExact( model.ProductionDate, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate ); if (!isValidEffDate || !isValidProDate) { return WebResponseContent.Instance.Error("格式无效或日期不合法"); } } Dt_MaterielInfo materielInfo = _basicRepository.MaterielInfoRepository.QueryFirst(x => x.MaterielCode == model.MaterielCode); if (materielInfo == null) { return WebResponseContent.Instance.Error($"未找到该物料的信息"); } //该收货单仓库是否有该物料 if (materielInfo.WarehouseId != receiveOrder.WarehouseId) { return WebResponseContent.Instance.Error($"该物料不属于该仓库"); } //无采购单进行收货 if (receiveOrder.ReceiveOrderType != ReceiveOrderTypeEnum.PO.ObjToInt()) { //获取具体批次及物料 Dt_ReceiveOrderDetail? detailNoPo = receiveOrder.Details.FirstOrDefault(x => x.LotNo == model.LotNo && x.MaterielCode == model.MaterielCode); lock (_rowNoLocker) { if (detailNoPo != null) { //原有收货明细增加收货数量 detailNoPo.ReceivedQuantity += model.Quantity; _unitOfWorkManage.BeginTran(); BaseDal.UpdateData(detailNoPo); _unitOfWorkManage.CommitTran(); } else { int rowNo = 0; if (receiveOrder.Details.Count > 0) { rowNo = receiveOrder.Details.Max(x => x.RowNo); } Dt_ReceiveOrderDetail receiveOrderDetail = new Dt_ReceiveOrderDetail() { PurchaseOrderNo = model.PurchaseOrderNo, ReceivedQuantity = model.Quantity, MaterielCode = model.MaterielCode, LotNo = model.LotNo, MaterielName = materielInfo.MaterielName, MaterielSpec = materielInfo.MaterielSpec, ReceiveOrderId = receiveOrder.ReceiveOrderId, PurchaseOrderDetailRowNo = rowNo + 1, IfInspection = materielInfo.IsCheck.ObjToInt(), CurrCode = "", PriceInTax = 0, TaxRate = "", RowNo = rowNo + 1, Unit = materielInfo.MaterielUnit }; if (receiveOrder.ReceiveOrderStatus == ReceiveOrderStatusEnum.NotStarted.ObjToInt()) { receiveOrder.ReceiveOrderStatus = ReceiveOrderStatusEnum.Receiving.ObjToInt(); } _unitOfWorkManage.BeginTran(); _inboundRepository.ReceiveOrderDetailRepository.AddData(receiveOrderDetail); _inboundRepository.ReceiveOrderRepository.UpdateData(receiveOrder); #region 注释 if (materielInfo.IsCheck == WhetherEnum.True) { Dt_CheckOrder checkOrder = _mapper.Map(receiveOrderDetail); checkOrder.OrderType = CheckTypeEnum.ReceiveCheck.ObjToInt(); checkOrder.ReceiveOrderNo = receiveOrder.ReceiveOrderNo; checkOrder.QualifiedQuantity = receiveOrderDetail.ReceivedQuantity; checkOrder.ReceiveDetailRowNo = receiveOrderDetail.RowNo; checkOrder.ScrappedQuantity = 0; checkOrder.ReturnQuantity = 0; checkOrder.DefectedQuantity = 0; _checkOrderRepository.AddData(checkOrder); } #endregion _unitOfWorkManage.CommitTran(); } return WebResponseContent.Instance.OK(); } } Dt_PurchaseOrder purchaseOrder = _inboundRepository.PurchaseOrderRepository.Db.Queryable().Where(x => x.PurchaseOrderNo == model.PurchaseOrderNo).Includes(x => x.Details).First(); if (purchaseOrder == null) { return WebResponseContent.Instance.Error($"未找到该采购单"); } if (purchaseOrder.Details.Count == 0) { return WebResponseContent.Instance.Error($"未找到该采购单明细数据"); } if (purchaseOrder.SupplierCode != receiveOrder.SuppliersId) { return WebResponseContent.Instance.Error($"供应商不一致,请新建收货单"); } if (purchaseOrder.PurchaseOrderStatus == PurchaseOrderStatusEnum.Received.ObjToInt()) { return WebResponseContent.Instance.Error($"该采购单收货已完成"); } Dt_PurchaseOrderDetail? purchaseOrderDetail = purchaseOrder.Details.Where(x => x.MaterielCode == model.MaterielCode && (x.PurchaseDetailStatus == PurchaseOrderDetailStatusEnum.NotReceived.ObjToInt() || x.PurchaseDetailStatus == PurchaseOrderDetailStatusEnum.Receiving.ObjToInt())).OrderBy(x=>x.Id).FirstOrDefault(); if (purchaseOrderDetail == null) { return WebResponseContent.Instance.Error($"该采购单明细收货已完成"); } //判断该采购单明细是否已存在明细 List details = receiveOrder.Details.Where(x => x.PurchaseOrderNo == model.PurchaseOrderNo && x.PurchaseOrderDetailRowNo == purchaseOrderDetail.RowNo && x.MaterielCode == model.MaterielCode).ToList(); if (details.Count >0 && details.Sum(x=>x.ReceivedQuantity) == purchaseOrderDetail.PurchaseDetailQuantity) { return WebResponseContent.Instance.Error($"该收货单明细已收货"); } //获取具体批次及物料 Dt_ReceiveOrderDetail? detail = details.FirstOrDefault(x => x.LotNo == model.LotNo && x.MaterielCode==model.MaterielCode); lock (_rowNoLocker) { if (detail != null) { //原有收货明细增加收货数量 detail.ReceivedQuantity += model.Quantity; purchaseOrderDetail.PurchaseDetailReceiveQty += model.Quantity; if (purchaseOrderDetail.PurchaseDetailReceiveQty > purchaseOrderDetail.PurchaseDetailQuantity) { return WebResponseContent.Instance.Error($"采购单行号{purchaseOrderDetail.RowNo}物料{purchaseOrderDetail.MaterielCode}数量溢出:{purchaseOrderDetail.PurchaseDetailReceiveQty - purchaseOrderDetail.PurchaseDetailQuantity}"); } if (purchaseOrderDetail.PurchaseDetailReceiveQty == purchaseOrderDetail.PurchaseDetailQuantity) { purchaseOrderDetail.PurchaseDetailStatus = PurchaseOrderDetailStatusEnum.Received.ObjToInt(); } else { purchaseOrderDetail.PurchaseDetailStatus = PurchaseOrderDetailStatusEnum.Receiving.ObjToInt(); } float sumQty = purchaseOrder.Details.Sum(x => x.PurchaseDetailReceiveQty); if (purchaseOrder.OrderQuantity == sumQty) { purchaseOrder.PurchaseOrderStatus = PurchaseOrderStatusEnum.Received.ObjToInt(); } else { purchaseOrder.PurchaseOrderStatus = PurchaseOrderStatusEnum.Receiving.ObjToInt(); } _unitOfWorkManage.BeginTran(); _inboundRepository.PurchaseOrderRepository.UpdateData(purchaseOrder); BaseDal.UpdateData(detail); _inboundRepository.PurchaseOrderDetailRepository.UpdateData(purchaseOrderDetail); _unitOfWorkManage.CommitTran(); } else { int rowNo = 0; if (receiveOrder.Details.Count > 0) { rowNo = receiveOrder.Details.Max(x => x.RowNo); } Dt_ReceiveOrderDetail receiveOrderDetail = new Dt_ReceiveOrderDetail() { PurchaseOrderNo = model.PurchaseOrderNo, ReceivedQuantity = model.Quantity, MaterielCode = model.MaterielCode, LotNo = model.LotNo, MaterielName=materielInfo.MaterielName, MaterielSpec=materielInfo.MaterielSpec, ReceiveOrderId = receiveOrder.ReceiveOrderId, PurchaseOrderDetailRowNo = purchaseOrderDetail.RowNo, IfInspection = materielInfo.IsCheck.ObjToInt(), CurrCode = "", PriceInTax = 0, TaxRate = "", RowNo = rowNo + 1, Unit = purchaseOrderDetail.Unit }; if (receiveOrder.ReceiveOrderStatus == ReceiveOrderStatusEnum.NotStarted.ObjToInt()) { receiveOrder.ReceiveOrderStatus = ReceiveOrderStatusEnum.Receiving.ObjToInt(); } //判断采购明细数量 if (purchaseOrderDetail.PurchaseDetailQuantity < model.Quantity) { return WebResponseContent.Instance.Error($"请核对采购单该物料数量"); } if (purchaseOrderDetail.PurchaseDetailReceiveQty > 0) { purchaseOrderDetail.PurchaseDetailReceiveQty += model.Quantity; } else { purchaseOrderDetail.PurchaseDetailReceiveQty = model.Quantity; } if (purchaseOrderDetail.PurchaseDetailReceiveQty > purchaseOrderDetail.PurchaseDetailQuantity) { return WebResponseContent.Instance.Error($"采购单行号{purchaseOrderDetail.RowNo}物料{purchaseOrderDetail.MaterielCode}数量溢出:{purchaseOrderDetail.PurchaseDetailReceiveQty - purchaseOrderDetail.PurchaseDetailQuantity}"); } if (purchaseOrderDetail.PurchaseDetailQuantity == purchaseOrderDetail.PurchaseDetailReceiveQty) { purchaseOrderDetail.PurchaseDetailStatus = PurchaseOrderDetailStatusEnum.Received.ObjToInt(); } else { purchaseOrderDetail.PurchaseDetailStatus = PurchaseOrderDetailStatusEnum.Receiving.ObjToInt(); } float sumQty = purchaseOrder.Details.Sum(x => x.PurchaseDetailReceiveQty); //+ model.Quantity _unitOfWorkManage.BeginTran(); BaseDal.AddData(receiveOrderDetail); if (purchaseOrder.OrderQuantity == sumQty) { purchaseOrder.PurchaseOrderStatus = PurchaseOrderStatusEnum.Received.ObjToInt(); _inboundRepository.PurchaseOrderRepository.UpdateData(purchaseOrder); } if(purchaseOrder.PurchaseOrderStatus== PurchaseOrderStatusEnum.NotReceived.ObjToInt()) { purchaseOrder.PurchaseOrderStatus = PurchaseOrderStatusEnum.Receiving.ObjToInt(); _inboundRepository.PurchaseOrderRepository.UpdateData(purchaseOrder); } _inboundRepository.ReceiveOrderRepository.UpdateData(receiveOrder); _inboundRepository.PurchaseOrderDetailRepository.UpdateData(purchaseOrderDetail); if (materielInfo.IsCheck == WhetherEnum.True) { Dt_CheckOrder checkOrder = _mapper.Map(receiveOrderDetail); checkOrder.OrderType = CheckTypeEnum.ReceiveCheck.ObjToInt(); checkOrder.ReceiveOrderNo = receiveOrder.ReceiveOrderNo; checkOrder.Result = CheckAcceptEnum.NotCheckAccept.ToString(); checkOrder.QualifiedQuantity = 0; checkOrder.ReceiveDetailRowNo = receiveOrderDetail.RowNo; checkOrder.WarehouseId = receiveOrder.WarehouseId; checkOrder.ScrappedQuantity = 0; checkOrder.MaterielSpec = materielInfo.MaterielSpec; checkOrder.ReturnQuantity = 0; checkOrder.DefectedQuantity = 0; int id = _checkOrderRepository.AddData(checkOrder); QMSReceiveCheckModel qMSReceiveCheck = new QMSReceiveCheckModel() { UniqueTag = id.ToString(), EntryNumber = receiveOrder.ReceiveOrderNo, MaterialCode = receiveOrderDetail.MaterielCode, MaterialName = receiveOrderDetail.MaterielName, Quantity = (decimal)receiveOrderDetail.ReceivedQuantity, SupplierCode = receiveOrder.SuppliersId, SupplierName = supplierInfo.SupplierName, BatchNumber = receiveOrderDetail.LotNo, DeliveryNumber = receiveOrder.DeliveryCode, PurchaseNumber = receiveOrderDetail.PurchaseOrderNo, RowNumber = receiveOrderDetail.RowNo, WarehouseCode = warehouse.WarehouseCode, ReceiptDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Remark = " " }; //调用QMS来料检验接口 string response = _invokeQMSService.InvokeReceiveCheckApi(qMSReceiveCheck); MesResponseContent mesResponseContent = response.DeserializeObject(); if (!mesResponseContent.BSucc) { throw new Exception(mesResponseContent.StrMsg); } ReceiveResultDTO? receiveResult = JsonConvert.DeserializeObject(mesResponseContent.Content.ToString()); if (receiveResult == null) { throw new Exception("接收QMS结果失败"); } Dt_CheckOrder _CheckOrder = _checkOrderRepository.QueryFirst(x => x.CheckOrderId == id); _CheckOrder.CheckOrderNo = receiveResult.InspectionNumber; _checkOrderRepository.UpdateData(_CheckOrder); } _unitOfWorkManage.CommitTran(); } return WebResponseContent.Instance.OK(); } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent ScaninnerCode(string innerCode) { WebResponseContent content = new WebResponseContent(); try { var innerCodes = innerCode.Split(','); var matCode = innerCodes.FirstOrDefault(x => x.Contains("M:"));//.Replace("M:", ""); if (matCode == null) throw new Exception("未获取到物料码"); var batchNo = innerCodes.FirstOrDefault(x => x.Contains("BS:"));//.Replace("BS:", "") if (batchNo == null) throw new Exception("未获取到批次号"); var purchaseOrderNo = innerCodes.FirstOrDefault(x => x.Contains("PO:"));//.Replace("PO:", "") if (purchaseOrderNo == null) throw new Exception("未获取到采购单号"); var qty = innerCodes.FirstOrDefault(x => x.Contains("Q:")); if (qty == null) throw new Exception("未获取到数量"); InnerCodeDTO innerCodeDTO = new InnerCodeDTO() { matCode = matCode.Replace("M:", ""), batchNo = batchNo.Replace("BS:", ""), purchaseOrderNo = purchaseOrderNo.Replace("PO:", ""), qty = Convert.ToInt32(qty.Replace("Q:", "")) }; content.OK("扫描成功", data: innerCodeDTO); } catch (Exception ex) { content.Error(ex.Message); } return content; } public WebResponseContent GetReceiveOrderInfos(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { string searchValue = saveModel.MainData["searchValue"].ToString(); string orderNo = saveModel.MainData["orderNo"].ToString(); Dt_ReceiveOrder receiveOrder = Db.Queryable().Where(x => x.ReceiveOrderNo == orderNo).First(); if (receiveOrder == null) throw new Exception($"未找到单据编号【{orderNo}】信息"); List receiveOrderDetails = new List(); if (string.IsNullOrEmpty(searchValue)) { receiveOrderDetails = Db.Queryable().Where(x => x.ReceiveOrderId == receiveOrder.ReceiveOrderId).ToList(); } else { receiveOrderDetails = Db.Queryable().Where(x => x.ReceiveOrderId == receiveOrder.ReceiveOrderId && x.MaterielCode == searchValue).ToList(); } content.OK(data: receiveOrderDetails); } catch (Exception ex) { content.Error(ex.Message); } return content; } } }