| | |
| | | using System.Security.Policy; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_Common.OrderEnum; |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Core.BaseRepository; |
| | | using WIDESEA_DTO.Allocate; |
| | |
| | | using WIDESEA_DTO.Inbound; |
| | | using WIDESEA_DTO.Outbound; |
| | | using WIDESEA_IBasicService; |
| | | using WIDESEA_IOutboundService; |
| | | using WIDESEA_Model.Models; |
| | | |
| | | namespace WIDESEA_BasicService |
| | |
| | | private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository; |
| | | private readonly IRepository<Dt_StockInfo> _stockInfoRepository; |
| | | private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository; |
| | | public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository) |
| | | |
| | | private readonly IOutboundOrderService _outboundOrderService; |
| | | private readonly IOutboundOrderDetailService _outboundOrderDetailService; |
| | | private readonly IOutStockLockInfoService _outStockLockInfoService; |
| | | public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IOutStockLockInfoService outStockLockInfoService) |
| | | { |
| | | _httpClientFactory = httpClientFactory; |
| | | _logger = logger; |
| | |
| | | _stockInfoDetailRepository = stockInfoDetailRepository; |
| | | _stockInfoRepository = stockInfoRepository; |
| | | _inboundOrderRepository = inboundOrderRepository; |
| | | _outboundOrderService = outboundOrderService; |
| | | _outboundOrderDetailService = outboundOrderDetailService; |
| | | _outStockLockInfoService = outStockLockInfoService; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <exception cref="HttpRequestException"></exception> |
| | | public async Task<ResponseModel> FeedbackInbound(FeedbackInboundRequestModel model) |
| | | { |
| | | string json =JsonConvert.SerializeObject(model, new JsonSerializerSettings |
| | | { |
| | | string json = JsonConvert.SerializeObject(model, new JsonSerializerSettings |
| | | { |
| | | ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() |
| | | }); |
| | | var content = new StringContent(json, Encoding.UTF8, "application/json"); |
| | |
| | | |
| | | return JsonConvert.DeserializeObject<ResponseModel>(body); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// åºåºåé¦ |
| | | /// </summary> |
| | |
| | | .ToList(); |
| | | var feeds = _feedbacktomesRepository.Db.Queryable<Dt_FeedbackToMes>().Where(x => x.OrderNo == orderNo && x.ReportStatus == 1).Select(o => o.PalletCode).ToList(); |
| | | var unreports = stockinfos.Where(x => !feeds.Contains(x.PalletCode)).ToList(); |
| | | if (unreports!=null && !unreports.Any()) { |
| | | if (unreports != null && !unreports.Any()) |
| | | { |
| | | return WebResponseContent.Instance.Error("没æéè¦åä¼ çæ°æ®"); |
| | | } |
| | | foreach (var item in unreports) |
| | |
| | | reqTime = DateTime.Now.ToString(), |
| | | business_type = inboundOrder.BusinessType, |
| | | factoryArea = inboundOrder.FactoryArea, |
| | | operationType=1, |
| | | Operator= inboundOrder.Operator, |
| | | operationType = 1, |
| | | Operator = inboundOrder.Operator, |
| | | orderNo = inboundOrder.UpperOrderNo, |
| | | status = inboundOrder.OrderStatus, |
| | | details = new List<FeedbackInboundDetailsModel>() |
| | | |
| | | }; |
| | | |
| | | |
| | | var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.SupplyCode, item.BatchNo, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode }) |
| | | .Select(group => new FeedbackInboundDetailsModel |
| | | { |
| | |
| | | supplyCode = group.Key.SupplyCode, |
| | | batchNo = group.Key.BatchNo, |
| | | lineNo = group.Key.InboundOrderRowNo, |
| | | qty = group.Sum(x=>x.BarcodeQty), |
| | | qty = group.Sum(x => x.BarcodeQty), |
| | | // warehouseCode = group.Key.WarehouseCode=="0"?"1072": group.Key.WarehouseCode, |
| | | warehouseCode =group.Key.WarehouseCode, |
| | | warehouseCode = group.Key.WarehouseCode, |
| | | unit = group.Key.BarcodeUnit, |
| | | barcodes = group.Select(row => new FeedbackBarcodesModel |
| | | { |
| | |
| | | |
| | | } |
| | | } |
| | | else if (inout == 2) |
| | | { |
| | | foreach (var orderNo in orderNos) |
| | | { |
| | | var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().FirstAsync(x => x.OrderNo == orderNo); |
| | | if (outboundOrder != null && outboundOrder.IsBatch == 0) |
| | | { |
| | | await HandleOutboundOrderToMESCompletion(outboundOrder, orderNo); |
| | | } |
| | | else if (outboundOrder != null && outboundOrder.IsBatch == 1) |
| | | { |
| | | await HandleOutboundOrderBatchToMESCompletion(outboundOrder, orderNo); |
| | | } |
| | | } |
| | | |
| | | } |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | private async Task HandleOutboundOrderBatchToMESCompletion(Dt_OutboundOrder outboundOrder, string orderNo) |
| | | { |
| | | |
| | | try |
| | | { |
| | | if (outboundOrder.ReturnToMESStatus == 1) |
| | | { |
| | | return; |
| | | } |
| | | var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) |
| | | .Where((o, item) => item.OrderNo == orderNo && item.ReturnToMESStatus != 1) |
| | | .Select((o, item) => o) |
| | | .ToListAsync(); |
| | | |
| | | var detailids = new List<int>(); |
| | | var allCompleted = true; |
| | | foreach (var detail in orderDetails.Where(x => x.ReturnToMESStatus == 0).ToList()) |
| | | { |
| | | if (detail.OverOutQuantity >= detail.NeedOutQuantity) |
| | | { |
| | | detailids.Add(detail.Id); |
| | | } |
| | | else |
| | | { |
| | | allCompleted = false; |
| | | } |
| | | } |
| | | if (orderDetails.Any(x => x.ReturnToMESStatus == 2)) |
| | | { |
| | | allCompleted = false; |
| | | } |
| | | |
| | | int newStatus = allCompleted ? (int)OutOrderStatusEnum.åºåºå®æ : (int)OutOrderStatusEnum.åºåºä¸; |
| | | |
| | | if (outboundOrder.OrderStatus != newStatus) |
| | | { |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.OrderStatus == newStatus) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | } |
| | | var documentno = UniqueValueGenerator.Generate(); |
| | | var feedmodel = new FeedbackOutboundRequestModel |
| | | { |
| | | reqCode = Guid.NewGuid().ToString(), |
| | | reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), |
| | | business_type = outboundOrder.BusinessType, |
| | | factoryArea = outboundOrder.FactoryArea, |
| | | operationType = 1, |
| | | Operator = outboundOrder.Operator, |
| | | orderNo = outboundOrder.UpperOrderNo, |
| | | documentsNO = documentno, |
| | | status = outboundOrder.OrderStatus, |
| | | details = new List<FeedbackOutboundDetailsModel>() |
| | | }; |
| | | |
| | | |
| | | foreach (var detail in orderDetails.Where(x => detailids.Contains(x.Id)).ToList()) |
| | | { |
| | | // è·å该æç»å¯¹åºçæ¡ç ä¿¡æ¯ï¼ä»éå®è®°å½ï¼ |
| | | var detailLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderNo == orderNo && detailids.Contains(x.OrderDetailId) && |
| | | x.Status == (int)OutLockStockStatusEnum.æ£é宿) |
| | | .ToListAsync(); |
| | | |
| | | var detailModel = new FeedbackOutboundDetailsModel |
| | | { |
| | | materialCode = detail.MaterielCode, |
| | | lineNo = detail.lineNo, // 注æï¼è¿éå¯è½éè¦è°æ´å段å |
| | | warehouseCode = detail.WarehouseCode, |
| | | qty = detail.OverOutQuantity, // 使ç¨è®¢åæç»çå·²åºåºæ°é |
| | | currentDeliveryQty = detail.OverOutQuantity, |
| | | unit = detail.Unit, |
| | | barcodes = detailLocks.Select(lockInfo => new WIDESEA_DTO.Outbound.BarcodesModel |
| | | { |
| | | barcode = lockInfo.CurrentBarcode, |
| | | supplyCode = lockInfo.SupplyCode, |
| | | batchNo = lockInfo.BatchNo, |
| | | unit = lockInfo.Unit, |
| | | qty = lockInfo.PickedQty // æ¡ç 级å«çæ°éä»ç¨éå®è®°å½ |
| | | }).ToList() |
| | | }; |
| | | |
| | | feedmodel.details.Add(detailModel); |
| | | } |
| | | |
| | | var result = await FeedbackOutbound(feedmodel); |
| | | if (result != null && result.code == 200) |
| | | { |
| | | |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => new Dt_OutboundOrderDetail |
| | | { |
| | | ReturnToMESStatus = 1, |
| | | documentsNO = documentno, |
| | | }) |
| | | .Where(x => detailids.Contains(x.Id)) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | if (allCompleted && newStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | { |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 1) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => new Dt_OutboundOrderDetail |
| | | { |
| | | ReturnToMESStatus = 2, |
| | | documentsNO = documentno, |
| | | }) |
| | | .Where(x => detailids.Contains(x.Id)) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"CheckAndUpdateOrderStatus失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | |
| | | private async Task HandleOutboundOrderToMESCompletion(Dt_OutboundOrder outboundOrder, string orderNo) |
| | | { |
| | | |
| | | try |
| | | { |
| | | if (outboundOrder.ReturnToMESStatus == 1) |
| | | { |
| | | return; |
| | | } |
| | | var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) |
| | | .Where((o, item) => item.OrderNo == orderNo) |
| | | .Select((o, item) => o) |
| | | .ToListAsync(); |
| | | |
| | | bool allCompleted = true; |
| | | foreach (var detail in orderDetails) |
| | | { |
| | | if (detail.OverOutQuantity < detail.NeedOutQuantity) |
| | | { |
| | | allCompleted = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | int newStatus = allCompleted ? (int)OutOrderStatusEnum.åºåºå®æ : (int)OutOrderStatusEnum.åºåºä¸; |
| | | |
| | | if (outboundOrder.OrderStatus != newStatus) |
| | | { |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.OrderStatus == newStatus) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | } |
| | | //åªææ£å¸¸åæ£å®ææ¶æåMESåé¦ |
| | | if (allCompleted && newStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | { |
| | | var feedmodel = new FeedbackOutboundRequestModel |
| | | { |
| | | reqCode = Guid.NewGuid().ToString(), |
| | | reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), |
| | | business_type = outboundOrder.BusinessType, |
| | | factoryArea = outboundOrder.FactoryArea, |
| | | operationType = 1, |
| | | Operator = outboundOrder.Operator, |
| | | orderNo = outboundOrder.UpperOrderNo, |
| | | documentsNO = outboundOrder.OrderNo, |
| | | status = outboundOrder.OrderStatus, |
| | | details = new List<FeedbackOutboundDetailsModel>() |
| | | }; |
| | | |
| | | |
| | | foreach (var detail in orderDetails) |
| | | { |
| | | // è·å该æç»å¯¹åºçæ¡ç ä¿¡æ¯ï¼ä»éå®è®°å½ï¼ |
| | | var detailLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderNo == orderNo && |
| | | x.OrderDetailId == detail.Id && |
| | | x.Status == (int)OutLockStockStatusEnum.æ£é宿) |
| | | .ToListAsync(); |
| | | |
| | | var detailModel = new FeedbackOutboundDetailsModel |
| | | { |
| | | materialCode = detail.MaterielCode, |
| | | lineNo = detail.lineNo, // 注æï¼è¿éå¯è½éè¦è°æ´å段å |
| | | warehouseCode = detail.WarehouseCode, |
| | | qty = detail.OverOutQuantity, // 使ç¨è®¢åæç»çå·²åºåºæ°é |
| | | currentDeliveryQty = detail.OverOutQuantity, |
| | | unit = detail.Unit, |
| | | barcodes = detailLocks.Select(lockInfo => new WIDESEA_DTO.Outbound.BarcodesModel |
| | | { |
| | | barcode = lockInfo.CurrentBarcode, |
| | | supplyCode = lockInfo.SupplyCode, |
| | | batchNo = lockInfo.BatchNo, |
| | | unit = lockInfo.Unit, |
| | | qty = lockInfo.PickedQty // æ¡ç 级å«çæ°éä»ç¨éå®è®°å½ |
| | | }).ToList() |
| | | }; |
| | | |
| | | feedmodel.details.Add(detailModel); |
| | | } |
| | | |
| | | var result = await FeedbackOutbound(feedmodel); |
| | | if (result != null && result.code == 200) |
| | | { |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 1) |
| | | .Where(x => x.OrderId == outboundOrder.Id) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 1) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"CheckAndUpdateOrderStatus失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | public static class UniqueValueGenerator |
| | | { |
| | | // åå计æ°å¨ï¼çº¿ç¨å®å
¨ï¼æ¯æ¬¡éå¢1ï¼é¿å
åä¸Tickséå¤ï¼ |
| | | private static long _counter = 0; |
| | | |
| | | /// <summary> |
| | | /// çæå¯ä¸å¼ï¼æ¯æé«å¹¶åï¼ |
| | | /// </summary> |
| | | /// <returns>æ ¼å¼ï¼yyyyMMdd + Ticks + 3ä½è®¡æ°å¨ï¼å¦2025112563867890123001ï¼</returns> |
| | | public static string Generate() |
| | | { |
| | | var now = DateTime.Now; |
| | | string datePart = now.ToString("yyyyMMdd"); |
| | | long ticksPart = now.Ticks; |
| | | |
| | | // ååéå¢è®¡æ°å¨ï¼å模1000ï¼ç¡®ä¿è®¡æ°å¨ä»
3ä½ï¼æ§å¶é¿åº¦ï¼ |
| | | long counterPart = Interlocked.Increment(ref _counter) % 1000; |
| | | |
| | | // æ¼æ¥ï¼è®¡æ°å¨è¡¥0为3ä½ï¼é¿å
使°ä¸ä¸è´ï¼ |
| | | return $"{datePart}{ticksPart}{counterPart:D3}"; |
| | | } |
| | | } |
| | | } |