using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Org.BouncyCastle.Asn1.Ocsp; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.OrderEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Helper; using WIDESEA_Core.HttpContextUser; using WIDESEA_Core.LogHelper; using WIDESEA_Core.Util; using WIDESEA_DTO.Base; using WIDESEA_DTO.ReturnMES; using WIDESEA_IBasicService; using WIDESEA_Model.Models; using static HslCommunication.Profinet.Knx.KnxCode; namespace WIDESEA_BasicService.MESOperation { public class FeedbackMesService : ServiceBase>, IFeedbackMesService { private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly HttpClientHelper _httpClientHelper; private readonly IRepository _outboundOrderRepository; private readonly IBasicService _basicService; private readonly IRepository _allocateRepository; private readonly IRepository _materialCodeInfoRepository; public FeedbackMesService(IRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, HttpClientHelper httpClientHelper, IRepository outboundOrderRepository, IBasicService basicService, IRepository allocateRepository, IRepository materialCodeInfoRepository) : base(BaseDal) { _unitOfWorkManage = unitOfWorkManage; _httpClientHelper = httpClientHelper; _outboundOrderRepository = outboundOrderRepository; _basicService = basicService; _allocateRepository = allocateRepository; _materialCodeInfoRepository = materialCodeInfoRepository; } public WebResponseContent OutboundFeedback(string orderNo) { WebResponseContent webResponse = new WebResponseContent(); try { Dt_OutboundOrder outboundOrder = _outboundOrderRepository.Db.Queryable().Where(x => x.OrderNo == orderNo).Includes(x => x.Details).First(); if (outboundOrder == null) { return webResponse = WebResponseContent.Instance.Error($"未找到对应的出库单信息"); } if(outboundOrder.OrderType == InOrderTypeEnum.ReCheck.ObjToInt() || outboundOrder.CreateType == OrderCreateTypeEnum.CreateInSystem.ObjToInt()) { return webResponse = WebResponseContent.Instance.OK($"该单据无需回传MES"); } List returnRecords = BaseDal.QueryData(x => x.OrderNo == orderNo && x.OrderId == outboundOrder.Id && x.ReturnStatus == 2); foreach (var item in returnRecords) { HttpResponseResult httpResponse = _httpClientHelper.Post(item.ApiUrl, item.RequestData); string rMsg = "成功"; bool success = httpResponse.IsSuccess && httpResponse.Data.Code == "200"; if (!success) { if (!httpResponse.IsSuccess) { rMsg = $"MES接口返回错误,HTTP代码:{httpResponse.StatusCode},信息:{httpResponse.ErrorMessage}"; } else if (httpResponse?.Data?.Code != "200") { rMsg = $"调用MES接口失败,代码:{httpResponse?.Data?.Code},信息:{httpResponse?.Data?.Message}"; } } item.ReturnCount += 1; item.ReturnStatus = success ? 1 : 2; item.HttpStatusCode = httpResponse.StatusCode.ObjToInt(); item.LastReturnTime = DateTime.Now; item.ResponseData = httpResponse.Content; item.SuccessTime = success ? DateTime.Now : null; } BaseDal.UpdateData(returnRecords); HttpResponseResult httpResponseResult = new HttpResponseResult(); string reqCode = Guid.NewGuid().ToString(); string reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string requestData = string.Empty; List lineNos = new List(); if (outboundOrder.OrderType == 0) { MaterialOutboundReturnDTO? returnDTO = BuildOutboundFeedbackData(outboundOrder); if (returnDTO == null) { return webResponse = WebResponseContent.Instance.Error($"构建回调对象失败"); } if (returnDTO.Details.Count <= 0) { if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 1)) { outboundOrder.ReturnToMESStatus = 1; } else if (returnRecords.Count(x => x.ReturnStatus == 2) > 0) { outboundOrder.ReturnToMESStatus = 4; } else if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 2)) { outboundOrder.ReturnToMESStatus = 2; } _outboundOrderRepository.UpdateData(outboundOrder); return webResponse = WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x=>x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条"); } string apiUrl = AppSettings.GetValue("MaterialOutboundFeedbackUrl"); returnDTO.ReqCode = reqCode; returnDTO.ReqTime = reqTime; JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; requestData = JsonConvert.SerializeObject(returnDTO, settings); lineNos = returnDTO.Details.Select(x => x.LineNo).ToList(); httpResponseResult = _httpClientHelper.Post(apiUrl, requestData); httpResponseResult.ApiUrl = apiUrl; } else { Dt_AllocateOrder allocateOrder = _allocateRepository.QueryFirst(x => x.OrderNo == outboundOrder.OrderNo); if (allocateOrder == null) { return webResponse = WebResponseContent.Instance.Error($"未找到对应的调拨单"); } AllocationReturnDTO? returnDTO = BuildAllocationFeedbackData(outboundOrder, allocateOrder.FromWarehouse, allocateOrder.ToWarehouse); if (returnDTO == null) { return webResponse = WebResponseContent.Instance.Error($"构建回调对象失败"); } if (returnDTO.Details.Count <= 0) { if(returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 1)) { outboundOrder.ReturnToMESStatus = 1; } else if(returnRecords.Count(x => x.ReturnStatus == 2)>0) { outboundOrder.ReturnToMESStatus = 4; } else if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 2)) { outboundOrder.ReturnToMESStatus = 2; } _outboundOrderRepository.UpdateData(outboundOrder); return webResponse = WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条"); } string apiUrl = AppSettings.GetValue("AllocationFeedbackUrl"); returnDTO.ReqCode = reqCode; returnDTO.ReqTime = reqTime; JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; requestData = JsonConvert.SerializeObject(returnDTO, settings); lineNos = returnDTO.Details.Select(x => x.LineNo).ToList(); httpResponseResult = _httpClientHelper.Post(apiUrl, requestData); httpResponseResult.ApiUrl = apiUrl; Logger.Add(requestData, httpResponseResult.Serialize()); } bool isSuccess = httpResponseResult.IsSuccess && httpResponseResult.Data.Code == "200"; string message = "成功"; if (!isSuccess) { if (!httpResponseResult.IsSuccess) { message = $"MES接口返回错误,HTTP代码:{httpResponseResult.StatusCode},信息:{httpResponseResult.ErrorMessage}"; } else if (httpResponseResult?.Data?.Code != "200") { message = $"调用MES接口失败,代码:{httpResponseResult?.Data?.Code},信息:{httpResponseResult?.Data?.Message}"; } } Dt_MesReturnRecord mesReturnRecord = new Dt_MesReturnRecord() { ApiUrl = httpResponseResult.ApiUrl, InterfaceType = outboundOrder.OrderType == 0 ? 1 : 3, OrderId = outboundOrder.Id, OrderNo = outboundOrder.OrderNo, RequestCode = reqCode, RequestData = requestData, FailureReason = message, LastReturnTime = DateTime.Now, HttpStatusCode = httpResponseResult.StatusCode.ObjToInt(), ResponseData = httpResponseResult.Content, ReturnType = 0, ReturnCount = 1, ReturnStatus = isSuccess ? 1 : 2, SuccessTime = isSuccess ? DateTime.Now : null }; _unitOfWorkManage.BeginTran(); _unitOfWorkManage.Db.Insertable(mesReturnRecord).ExecuteCommand(); List outboundOrderDetails = outboundOrder.Details.Where(x => lineNos.Contains(x.lineNo)).ToList(); outboundOrderDetails.ForEach(x => { if (x.OverOutQuantity == x.OrderQuantity - x.MoveQty) { x.ReturnToMESStatus = isSuccess ? 1 : 2; } else { x.ReturnToMESStatus = isSuccess ? 3 : 4; } x.CurrentDeliveryQty = 0; x.ReturnJsonData = ""; }); mesReturnRecord.ReturnType = outboundOrder.Details.Count == outboundOrderDetails.Count ? 1 : 2; if (outboundOrder.Details.Count == outboundOrderDetails.Count && outboundOrderDetails.All(x => x.ReturnToMESStatus == 1 || x.ReturnToMESStatus == 2)) { outboundOrder.ReturnToMESStatus = isSuccess ? 1 : 2; } else { outboundOrder.ReturnToMESStatus = isSuccess ? 3 : 4; } _outboundOrderRepository.Db.Updateable(outboundOrderDetails).ExecuteCommand(); _outboundOrderRepository.UpdateData(outboundOrder); _unitOfWorkManage.CommitTran(); int successCount = returnRecords.Where(x => x.ReturnStatus == 1).Count() + (isSuccess ? 1 : 0); int failCount = returnRecords.Where(x => x.ReturnStatus == 2).Count() + (!isSuccess ? 1 : 0); webResponse.Status = true; webResponse.Message = $"回调成功条数:{successCount},回调失败条数:{failCount}"; return webResponse; } catch (Exception ex) { return webResponse = WebResponseContent.Instance.Error(ex.Message); } finally { Logger.Add(orderNo, webResponse.Serialize()); } } public AllocationReturnDTO? BuildAllocationFeedbackData(Dt_OutboundOrder outboundOrder, string fromWarehouse, string toWarehouse) { try { List details = outboundOrder.Details; List returnDetails = new List(); foreach (var detail in details) { List? barcodes = JsonConvert.DeserializeObject>(detail.ReturnJsonData); if (barcodes != null && barcodes.Any()) { UnitConvertResultDTO currentResult = _basicService.UnitQuantityConvert(detail.MaterielCode, detail.Unit, detail.BarcodeUnit, detail.CurrentDeliveryQty); UnitConvertResultDTO totalResult = _basicService.UnitQuantityConvert(detail.MaterielCode, detail.Unit, detail.BarcodeUnit, detail.OrderQuantity); returnDetails.Add(new AllocationDetail { Barcodes = barcodes, BatchNo = detail.BatchNo, LineNo = detail.lineNo, MaterialCode = detail.MaterielCode, Qty = totalResult.ToQuantity, WarehouseCode = detail.WarehouseCode, Unit = detail.BarcodeUnit }); } } AllocationReturnDTO outboundReturnDTO = new AllocationReturnDTO() { Business_type = outboundOrder.BusinessType, Details = returnDetails, FactoryArea = outboundOrder.FactoryArea, OperationType = 1, OrderNo = outboundOrder.UpperOrderNo, FromWarehouse = fromWarehouse, ToWarehouse = toWarehouse, Operator = App.User.UserName }; return outboundReturnDTO; } catch (Exception ex) { return null; } } public void MaterialOutboundFeedback(Dt_OutboundOrder outboundOrder) { try { MaterialOutboundReturnDTO? returnDTO = BuildOutboundFeedbackData(outboundOrder); if (returnDTO != null) { string apiUrl = ""; HttpResponseResult httpResponseResult = _httpClientHelper.Post(apiUrl, returnDTO.Serialize()); bool isSuccess = httpResponseResult.IsSuccess && httpResponseResult.Data != null && httpResponseResult.Data.Code == "200"; string message = ""; if (!isSuccess) { if (httpResponseResult.IsSuccess) { message = $"MES接口返回错误,HTTP代码:{httpResponseResult.StatusCode},信息:{httpResponseResult.ErrorMessage}"; } else if (httpResponseResult.Data.Code != "200") { message = $"调用MES接口失败,代码:{httpResponseResult.Data.Code},信息:{httpResponseResult.Data.Message}"; } } Dt_MesReturnRecord mesReturnRecord = new Dt_MesReturnRecord() { ApiUrl = apiUrl, InterfaceType = 1, OrderId = outboundOrder.Id, OrderNo = outboundOrder.OrderNo, RequestCode = returnDTO.ReqCode, RequestData = returnDTO.Serialize(), FailureReason = message, LastReturnTime = DateTime.Now, HttpStatusCode = httpResponseResult.StatusCode.ObjToInt(), ResponseData = httpResponseResult.Content, ReturnType = 0, ReturnCount = 1, ReturnStatus = httpResponseResult.IsSuccess ? 1 : 2, SuccessTime = httpResponseResult.IsSuccess ? DateTime.Now : null }; _unitOfWorkManage.BeginTran(); _unitOfWorkManage.Db.Insertable(mesReturnRecord).ExecuteCommand(); List lineNos = returnDTO.Details.Select(x => x.LineNo).ToList(); List outboundOrderDetails = outboundOrder.Details.Where(x => lineNos.Contains(x.lineNo)).ToList(); outboundOrderDetails.ForEach(x => { if (x.OverOutQuantity == x.OrderQuantity - x.MoveQty) { x.ReturnToMESStatus = isSuccess ? 1 : 2; } else { x.ReturnToMESStatus = isSuccess ? 3 : 4; } x.CurrentDeliveryQty = 0; x.ReturnJsonData = ""; }); _outboundOrderRepository.Db.Updateable(outboundOrderDetails).ExecuteCommand(); _unitOfWorkManage.CommitTran(); } } catch (Exception ex) { throw new Exception(ex.Message); } } public MaterialOutboundReturnDTO? BuildOutboundFeedbackData(Dt_OutboundOrder outboundOrder) { try { List details = outboundOrder.Details; List returnDetails = new List(); foreach (var detail in details) { if (!string.IsNullOrWhiteSpace(detail.ReturnJsonData)) { List? barcodes = JsonConvert.DeserializeObject>(detail.ReturnJsonData); if (barcodes != null && barcodes.Any()) { UnitConvertResultDTO currentResult = _basicService.UnitQuantityConvert(detail.MaterielCode, detail.Unit, detail.BarcodeUnit, detail.CurrentDeliveryQty); UnitConvertResultDTO totalResult = _basicService.UnitQuantityConvert(detail.MaterielCode, detail.Unit, detail.BarcodeUnit, detail.OrderQuantity); returnDetails.Add(new MaterialOutboundDetail { Barcodes = barcodes, CurrentDeliveryQty = currentResult.ToQuantity, LineNo = detail.lineNo, MaterialCode = detail.MaterielCode, Qty = totalResult.ToQuantity, WarehouseCode = detail.WarehouseCode, Unit = detail.BarcodeUnit }); } } } MaterialOutboundReturnDTO outboundReturnDTO = new MaterialOutboundReturnDTO() { Business_type = outboundOrder.BusinessType, Details = returnDetails, DocumentsNO = _basicService.CreateCodeByRule("OutboundOrderRule"), FactoryArea = outboundOrder.FactoryArea, OperationType = 1, Operator = App.User.UserName, OrderNo = outboundOrder.UpperOrderNo, Status = 1 }; return outboundReturnDTO; } catch (Exception ex) { return null; } } public WebResponseContent BarcodeFeedback(string newBarcode) { try { Dt_MaterialCodeInfo materialCodeInfo = _materialCodeInfoRepository.QueryFirst(x => x.NewBarcode == newBarcode, new Dictionary { { nameof(Dt_MaterialCodeInfo.Id), OrderByType.Desc } }); if (materialCodeInfo == null) { return WebResponseContent.Instance.Error($"未找到物料条码信息{newBarcode}"); } string apiUrl = AppSettings.GetValue("BarcodeFeedbackUrl"); BarcodeReturnDTO returnDTO = new BarcodeReturnDTO() { BatchNo = materialCodeInfo.BatchNo, FactoryArea = materialCodeInfo.FactoryArea, OperationType = 1, MaterialCode = materialCodeInfo.MaterialCode, NewmaterialCode = materialCodeInfo.NewBarcode, OldmaterialCode = materialCodeInfo.OldBarcode, Operator = materialCodeInfo.Creater, Qty = materialCodeInfo.AfterQuantity, SupplyCode = materialCodeInfo.SuplierCode, Unit = materialCodeInfo.Unit, WarehouseCode = materialCodeInfo.WarehouseCode, OldQty = materialCodeInfo.OriginalQuantity }; string reqCode = Guid.NewGuid().ToString(); string reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; string requestData = JsonConvert.SerializeObject(returnDTO, settings); HttpResponseResult httpResponseResult = _httpClientHelper.Post(apiUrl, requestData); httpResponseResult.ApiUrl = apiUrl; bool isSuccess = httpResponseResult.IsSuccess && httpResponseResult.Data.Code == "200"; string message = "成功"; if (!isSuccess) { if (!httpResponseResult.IsSuccess) { message = $"MES接口返回错误,HTTP代码:{httpResponseResult.StatusCode},信息:{httpResponseResult.ErrorMessage}"; } else if (httpResponseResult.Data.Code != "200") { message = $"调用MES接口失败,代码:{httpResponseResult.Data.Code},信息:{httpResponseResult.Data.Message}"; } } Dt_MesReturnRecord mesReturnRecord = new Dt_MesReturnRecord() { ApiUrl = httpResponseResult.ApiUrl, InterfaceType = 1, OrderId = materialCodeInfo.OrderId ?? 0, OrderNo = materialCodeInfo.OrderNo ?? "", RequestCode = reqCode, RequestData = requestData, FailureReason = message, LastReturnTime = DateTime.Now, HttpStatusCode = httpResponseResult.StatusCode.ObjToInt(), ResponseData = httpResponseResult.Content, ReturnType = 0, ReturnCount = 1, ReturnStatus = httpResponseResult.IsSuccess ? 1 : 2, SuccessTime = httpResponseResult.IsSuccess ? DateTime.Now : null }; _unitOfWorkManage.BeginTran(); _unitOfWorkManage.Db.Insertable(mesReturnRecord).ExecuteCommand(); materialCodeInfo.ReturnStatus = httpResponseResult.IsSuccess ? 1 : 2; _materialCodeInfoRepository.UpdateData(materialCodeInfo); _unitOfWorkManage.CommitTran(); WebResponseContent responseContent = new WebResponseContent(); responseContent.Status = isSuccess; responseContent.Message = message; return responseContent; } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } } }