| | |
| | | using Dm.filter; |
| | | using MailKit.Search; |
| | | using Microsoft.AspNetCore.Http; |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using MailKit.Search; |
| | | using Microsoft.Extensions.Logging; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Reflection.Metadata; |
| | | using System.Text; |
| | | using System.Text.Json; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_BasicService; |
| | | using WIDESEA_Common.CommonEnum; |
| | | using WIDESEA_Common.LocationEnum; |
| | | using WIDESEA_Common.OrderEnum; |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Common.TaskEnum; |
| | |
| | | using WIDESEA_Core.Enums; |
| | | using WIDESEA_Core.Helper; |
| | | using WIDESEA_Core.Utilities; |
| | | using WIDESEA_DTO.Allocate; |
| | | using WIDESEA_DTO.Basic; |
| | | using WIDESEA_DTO.Inbound; |
| | | using WIDESEA_DTO.Outbound; |
| | |
| | | return WebResponseContent.Instance.Error("æªæ¾å°å¯¹åºçä»»å¡ä¿¡æ¯"); |
| | | |
| | | //åæéè¦ååºçè´§ç© |
| | | //var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id); |
| | | //if (!returnAnalysis.HasItemsToReturn) |
| | | // return await HandleNoReturnItems(orderNo, palletCode, task); |
| | | |
| | | var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id); |
| | | if (!statusAnalysis.HasItemsToReturn) |
| | | { |
| | | var result = await HandleNoReturnItems(orderNo, palletCode, task, stockInfo.Id); |
| | | _unitOfWorkManage.CommitTran(); |
| | | return result; |
| | | try |
| | | { |
| | | var result = await HandleNoReturnItems(orderNo, palletCode, task, stockInfo.Id); |
| | | _unitOfWorkManage.CommitTran(); |
| | | if (result.Status) |
| | | { |
| | | task.PalletType = PalletTypeEnum.Empty.ObjToInt(); |
| | | await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, TaskTypeEnum.InEmpty, PalletTypeEnum.Empty.ObjToInt()); |
| | | } |
| | | return result; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | _logger.LogError($"ReturnRemaining ååºç©ºç®±å¤±è´¥ - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}"); |
| | | return WebResponseContent.Instance.Error($"ååºç©ºç®±æä½å¤±è´¥: {ex.Message}"); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | // 4. æ£æ¥æ¯å¦æè¿è¡ä¸çä»»å¡ |
| | | // æ£æ¥æ¯å¦æè¿è¡ä¸çä»»å¡ |
| | | if (statusAnalysis.HasActiveTasks) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æç {palletCode} æè¿è¡ä¸çä»»å¡ï¼ä¸è½æ§è¡ååºæä½"); |
| | |
| | | |
| | | private async Task<ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>> ValidatePickingRequest(string orderNo, string palletCode, string barcode) |
| | | { |
| | | // 1. åºç¡åæ°éªè¯ |
| | | // åºç¡åæ°éªè¯ |
| | | if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode)) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error("订åå·ãæçç åæ¡ç ä¸è½ä¸ºç©º"); |
| | | |
| | | // 2. æ¥æ¾ææçéå®ä¿¡æ¯ |
| | | // æ¥æ¾ææçéå®ä¿¡æ¯ |
| | | var lockInfo = await FindValidLockInfo(orderNo, palletCode, barcode); |
| | | if (lockInfo == null) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æªæ¾å°ææçéå®ä¿¡æ¯"); |
| | | |
| | | // 3. æ£æ¥è®¢åç¶æ |
| | | // æ£æ¥è®¢åç¶æ |
| | | var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .FirstAsync(); |
| | |
| | | if (order?.OrderStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"订å{orderNo}已宿ï¼ä¸è½ç»§ç»åæ£"); |
| | | |
| | | // 4. è·å订åæç» |
| | | // è·å订åæç» |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == lockInfo.OrderDetailId); |
| | | |
| | | if (orderDetail == null) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æªæ¾å°è®¢åæç»"); |
| | | |
| | | // 5. æ£æ¥è®¢åæç»æ°é |
| | | // æ£æ¥è®¢åæç»æ°é |
| | | if (orderDetail.OverOutQuantity >= orderDetail.NeedOutQuantity) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"订åæç»éæ±æ°é已满足"); |
| | | |
| | | // 6. è·ååºåæç» |
| | | // è·ååºåæç» |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId && |
| | | x.Status != StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt()) |
| | |
| | | if (stockDetail == null) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æ æçæ¡ç æç©æç¼ç "); |
| | | |
| | | // 7. æ£æ¥åºåç¶æåæ°é |
| | | // æ£æ¥åºåç¶æåæ°é |
| | | if (stockDetail.StockQuantity <= 0) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æ¡ç {barcode}åºåä¸è¶³"); |
| | | |
| | | if (stockDetail.Status != StockStatusEmun.åºåºéå®.ObjToInt()) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æ¡ç {barcode}ç¶æä¸æ£ç¡®ï¼æ æ³åæ£"); |
| | | |
| | | // 8. æ£æ¥æ¯å¦éå¤åæ£ |
| | | //æ£æ¥æ¯å¦éå¤åæ£ |
| | | var existingPicking = await Db.Queryable<Dt_PickingRecord>() |
| | | .Where(x => x.Barcode == barcode && x.OrderNo == orderNo && x.PalletCode == palletCode && x.OutStockLockId == lockInfo.Id) |
| | | .FirstAsync(); |
| | |
| | | private async Task HandleFullPicking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail, |
| | | decimal actualQty, PickingResult result) |
| | | { |
| | | // 1. æ´æ°åºå |
| | | // æ´æ°åºå |
| | | stockDetail.StockQuantity = 0; |
| | | stockDetail.OutboundQuantity = 0; |
| | | stockDetail.Status = StockStatusEmun.åºåºå®æ.ObjToInt(); |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // 2. æ´æ°éå®ä¿¡æ¯ |
| | | // æ´æ°éå®ä¿¡æ¯ |
| | | lockInfo.PickedQty += actualQty; |
| | | lockInfo.Status = (int)OutLockStockStatusEnum.æ£é宿; |
| | | lockInfo.Operator = App.User.UserName; |
| | |
| | | decimal stockOutQty = stockQuantity; |
| | | decimal remainingAssignQty = actualQty - stockQuantity; |
| | | |
| | | // 1. æ´æ°åºå |
| | | // æ´æ°åºå |
| | | stockDetail.StockQuantity = 0; |
| | | stockDetail.OutboundQuantity = 0; |
| | | stockDetail.Status = StockStatusEmun.åºåºå®æ.ObjToInt(); |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // 2. æ´æ°éå®ä¿¡æ¯ |
| | | // æ´æ°éå®ä¿¡æ¯ |
| | | lockInfo.PickedQty += stockOutQty; |
| | | lockInfo.AssignQuantity = remainingAssignQty; |
| | | lockInfo.Operator = App.User.UserName; |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | // 3. æ´æ°æå
è®°å½ç¶æ |
| | | // æ´æ°æå
è®°å½ç¶æ |
| | | await UpdateSplitRecordsStatus(stockDetail.Barcode); |
| | | |
| | | result.ActualPickedQty = stockOutQty; |
| | |
| | | |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Success((pickingRecord, lockInfo, orderDetail)); |
| | | } |
| | | /// <summary> |
| | | /// æ£æ¥æ¡ç æ¯å¦å·²ç»ååº |
| | | /// </summary> |
| | | private async Task<bool> IsBarcodeReturned(string barcode, int stockId) |
| | | { |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == barcode && it.StockId == stockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail == null) |
| | | return false; |
| | | |
| | | // å¦æç¶ææ¯å
¥åºç¡®è®¤æå
¥åºå®æï¼è¯´æå·²ç»ååº |
| | | return stockDetail.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | stockDetail.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£æ¥éå®ä¿¡æ¯å¯¹åºçæ¡ç æ¯å¦å·²ç»ååº |
| | |
| | | |
| | | #region ååºæä½ç§ææ¹æ³ |
| | | |
| | | private async Task<Dt_StockInfo> GetStockInfo(string palletCode) |
| | | { |
| | | return await _stockInfoService.Db.Queryable<Dt_StockInfo>() |
| | | .FirstAsync(x => x.PalletCode == palletCode); |
| | | } |
| | | /// <summary> |
| | | /// æ£æ¥æ´ä¸ªæçæ¯å¦å·²ç»ååº |
| | | /// </summary> |
| | |
| | | |
| | | private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode, Dt_Task originalTask, int stockInfoId) |
| | | { |
| | | // æ£æ¥æ¯å¦ææè´§ç©é½å·²æ£é宿 |
| | | //var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | // .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode) |
| | | // .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.æ£é宿); |
| | | |
| | | //if (allPicked) |
| | | //{ |
| | | // // å é¤åå§åºåºä»»å¡ ç»ç©ºç 空çååº |
| | | // //await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync(); |
| | | // return WebResponseContent.Instance.OK("ææè´§ç©å·²æ£éå®æï¼æç为空"); |
| | | //} |
| | | //else |
| | | //{ |
| | | // // å é¤åå§åºåºä»»å¡ |
| | | // //await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync(); |
| | | // return WebResponseContent.Instance.Error("没æéè¦ååºçå©ä½è´§ç©"); |
| | | //} |
| | | try |
| | | { |
| | | var locationtype = 0; |
| | |
| | | _stockInfoService.AddMaterielGroup(emptystockInfo); |
| | | //空æçå¦ä½å¤ç è¿æä¸ä¸ªåºåºä»»å¡è¦å¤çã |
| | | originalTask.PalletType = PalletTypeEnum.Empty.ObjToInt(); |
| | | |
| | | await CreateReturnTaskAndHandleESS(orderNo, palletCode, originalTask, TaskTypeEnum.InEmpty, PalletTypeEnum.Empty.ObjToInt()); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | |
| | | { |
| | | _logger.LogInformation($"å¼å§éæ¾éå®ä»¥ä¾¿éæ°åé
- 订å: {orderNo}, æç: {palletCode}"); |
| | | |
| | | // 1. å¤çæªåæ£çåºåºéå®è®°å½ - å®å
¨éæ¾ |
| | | // å¤çæªåæ£çåºåºéå®è®°å½ - å®å
¨éæ¾ |
| | | if (analysis.HasRemainingLocks) |
| | | { |
| | | await ReleaseRemainingLocks(analysis.RemainingLocks); |
| | | } |
| | | |
| | | // 2. å¤çå·²ååºçéå®è®°å½ - å 餿æ è®°ä¸ºæ æ |
| | | // å¤çå·²ååºçéå®è®°å½ - å 餿æ è®°ä¸ºæ æ |
| | | await CleanupReturnedLocks(orderNo, palletCode); |
| | | |
| | | // 3. é置订åæç»çé宿°é |
| | | // é置订åæç»çé宿°é |
| | | await ResetOrderDetailLockQuantities(analysis); |
| | | |
| | | _logger.LogInformation($"éå®éæ¾å®æ - 订å: {orderNo}, æç: {palletCode}"); |
| | |
| | | |
| | | } |
| | | |
| | | private async Task UpdateOrderDetailsOnReturn(List<Dt_OutStockLockInfo> remainingLocks) |
| | | { |
| | | // æè®¢åæç»åç» |
| | | var orderDetailGroups = remainingLocks.GroupBy(x => x.OrderDetailId); |
| | | |
| | | foreach (var group in orderDetailGroups) |
| | | { |
| | | var orderDetailId = group.Key; |
| | | var totalReturnQty = group.Sum(x => x.AssignQuantity - x.PickedQty); |
| | | |
| | | // è·åå½å订åæç» |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == orderDetailId); |
| | | |
| | | if (orderDetail != null) |
| | | { |
| | | // è°æ´å·²æ£éæ°éåå·²åºåºæ°é |
| | | decimal newPickedQty = Math.Max(0, orderDetail.PickedQty - totalReturnQty); |
| | | decimal newOverOutQuantity = Math.Max(0, orderDetail.OverOutQuantity - totalReturnQty); |
| | | |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => new Dt_OutboundOrderDetail |
| | | { |
| | | PickedQty = newPickedQty, |
| | | OverOutQuantity = newOverOutQuantity, |
| | | }) |
| | | .Where(it => it.Id == orderDetailId) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private async Task HandlePalletStockGoodsReturn(List<Dt_StockInfoDetail> palletStockGoods) |
| | | { |
| | |
| | | { |
| | | try |
| | | { |
| | | // 1. åéæµå¨ä¿¡å· |
| | | // åéæµå¨ä¿¡å· |
| | | var moveResult = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest |
| | | { |
| | | slotCode = movestations[targetAddress], |
| | |
| | | |
| | | //if (moveResult) |
| | | //{ |
| | | // 2. å建ååºä»»å¡ |
| | | // å建ååºä»»å¡ |
| | | var essTask = new TaskModel() |
| | | { |
| | | taskType = "putaway", |
| | |
| | | } |
| | | } |
| | | |
| | | private async Task HandleOrderCompletion(Dt_OutboundOrder outboundOrder, string orderNo) |
| | | { |
| | | // è°æ¨åºåºå鿣åºåºä¸éè¦åé¦MES |
| | | if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt()) |
| | | { |
| | | var allocate = _allocateService.Repository.QueryData(x => x.UpperOrderNo == outboundOrder.UpperOrderNo).First(); |
| | | var allocatefeedmodel = new AllocateDto |
| | | { |
| | | ReqCode = Guid.NewGuid().ToString(), |
| | | ReqTime = DateTime.Now.ToString(), |
| | | BusinessType = "2", |
| | | |
| | | FactoryArea = outboundOrder.FactoryArea, |
| | | OperationType = 1, |
| | | Operator = App.User.UserName, |
| | | OrderNo = outboundOrder.UpperOrderNo, |
| | | // documentsNO = outboundOrder.OrderNo, |
| | | // status = outboundOrder.OrderStatus, |
| | | fromWarehouse = allocate?.FromWarehouse ?? "", |
| | | toWarehouse = allocate?.ToWarehouse ?? "", |
| | | Details = new List<AllocateDtoDetail>() |
| | | |
| | | }; |
| | | // åªè·åå·²æ£é宿çéå®è®°å½ |
| | | var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.æ£é宿) |
| | | .ToListAsync(); |
| | | |
| | | var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.BarcodeUnit, item.WarehouseCode }) |
| | | .Select(group => new AllocateDtoDetail |
| | | { |
| | | MaterialCode = group.Key.MaterielCode, |
| | | LineNo = group.Key.lineNo, |
| | | WarehouseCode = group.Key.WarehouseCode, |
| | | Qty = group.Sum(x => x.PickedQty), |
| | | |
| | | Unit = group.Key.BarcodeUnit, |
| | | Barcodes = group.Select(row => new BarcodeInfo |
| | | { |
| | | Barcode = row.CurrentBarcode, |
| | | SupplyCode = row.SupplyCode, |
| | | BatchNo = row.BatchNo, |
| | | Unit = row.BarcodeUnit, |
| | | Qty = row.PickedQty |
| | | }).ToList() |
| | | |
| | | |
| | | }).ToList(); |
| | | allocatefeedmodel.Details = groupedData; |
| | | |
| | | var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel); |
| | | 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 => new Dt_OutboundOrder |
| | | { |
| | | ReturnToMESStatus = 1, |
| | | Operator = App.User.UserName, |
| | | }).Where(x => x.OrderNo == orderNo).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt()) |
| | | { |
| | | |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | 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 = App.User.UserName, |
| | | orderNo = outboundOrder.UpperOrderNo, |
| | | documentsNO = outboundOrder.OrderNo, |
| | | status = outboundOrder.OrderStatus, |
| | | details = new List<FeedbackOutboundDetailsModel>() |
| | | }; |
| | | |
| | | // åªè·åå·²æ£é宿çéå®è®°å½ |
| | | var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderNo == orderNo && (x.Status == (int)OutLockStockStatusEnum.æ£é宿 || x.Status == (int)OutLockStockStatusEnum.å·²ååº)) |
| | | .ToListAsync(); |
| | | |
| | | var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.BarcodeUnit, item.WarehouseCode }) |
| | | .Select(group => new FeedbackOutboundDetailsModel |
| | | { |
| | | materialCode = group.Key.MaterielCode, |
| | | lineNo = group.Key.lineNo, |
| | | warehouseCode = group.Key.WarehouseCode, |
| | | qty = group.Sum(x => x.PickedQty), |
| | | currentDeliveryQty = group.Sum(x => x.PickedQty), |
| | | unit = group.Key.BarcodeUnit, |
| | | barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel |
| | | { |
| | | barcode = row.CurrentBarcode, |
| | | supplyCode = row.SupplyCode, |
| | | batchNo = row.BatchNo, |
| | | unit = row.BarcodeUnit, |
| | | qty = row.PickedQty |
| | | }).ToList() |
| | | }).ToList(); |
| | | |
| | | feedmodel.details = groupedData; |
| | | |
| | | var result = await _invokeMESService.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 => new Dt_OutboundOrder |
| | | { |
| | | ReturnToMESStatus = 1, |
| | | Operator = App.User.UserName, |
| | | }) |
| | | |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | |
| | | _logger.LogError($"FeedbackOutboundæå - OrderNo: {orderNo}, {JsonSerializer.Serialize(result)}"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"FeedbackOutbound失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 空æç |
| | |
| | | { |
| | | try |
| | | { |
| | | // 1. æ¥æ¾ææä¸è¯¥è®¢ååæçç¸å
³çä»»å¡ |
| | | // æ¥æ¾ææä¸è¯¥è®¢ååæçç¸å
³çä»»å¡ |
| | | var tasks = await _taskRepository.Db.Queryable<Dt_Task>().Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode).ToListAsync(); |
| | | |
| | | if (tasks.Any()) |
| | |
| | | _logger.LogInformation($"订å {orderNo} è¿æå
¶ä»æçå¨å¤çï¼ä¸æ´æ°è®¢åç¶æ"); |
| | | } |
| | | |
| | | // 3. æ´æ°æ£éè®°å½ç¶æï¼å¯éï¼ |
| | | // æ´æ°æ£éè®°å½ç¶æï¼å¯éï¼ |
| | | await UpdatePickingRecordsStatus(orderNo, palletCode); |
| | | |
| | | } |
| | |
| | | |
| | | _logger.LogInformation($"订å {orderNo} å·²æ 记为åºåºå®æ"); |
| | | |
| | | // åMESåé¦è®¢å宿ï¼å¦æéè¦ï¼ |
| | | //await HandleOrderCompletion(outboundOrder, orderNo); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // è¿éå¯ä»¥æ ¹æ®éè¦æ´æ°æ£éè®°å½çç¶æåæ®µ |
| | | // ä¾å¦ï¼pickingRecord.Status = (int)PickingStatusEnum.已宿; |
| | | |
| | | _logger.LogInformation($"æ¾å°{pickingRecords.Count}æ¡æ£éè®°å½ - 订å: {orderNo}, æç: {palletCode}"); |
| | | |
| | | } |
| | |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£æ¥æçæ¯å¦ä¸ºç©º |
| | | /// </summary> |
| | | private async Task<bool> IsPalletEmpty(string orderNo, string palletCode) |
| | | { |
| | | try |
| | | { |
| | | // è·ååºåä¿¡æ¯ |
| | | var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>() |
| | | .Where(x => x.PalletCode == palletCode) |
| | | .FirstAsync(); |
| | | |
| | | if (stockInfo == null) |
| | | return false; |
| | | |
| | | // 使ç¨ç»ä¸çç¶æåæ |
| | | var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id); |
| | | return statusAnalysis.IsEmptyPallet; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogWarning($"æ£æ¥æçæ¯å¦ä¸ºç©ºå¤±è´¥ - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// æ£æ¥å¹¶å¤ç空æç |
| | | /// </summary> |
| | | private async Task<bool> CheckAndHandleEmptyPallet(string orderNo, string palletCode) |
| | | { |
| | | try |
| | | { |
| | | // 1. è·ååºåä¿¡æ¯ |
| | | var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>() |
| | | .Where(x => x.PalletCode == palletCode) |
| | | .FirstAsync(); |
| | | |
| | | if (stockInfo == null) |
| | | { |
| | | _logger.LogWarning($"æªæ¾å°æç {palletCode} çåºåä¿¡æ¯"); |
| | | return false; |
| | | } |
| | | |
| | | // 2. 使ç¨ç»ä¸çç¶æåæ |
| | | var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id); |
| | | |
| | | // 3. æ£æ¥æ¯å¦ä¸ºç©ºæç䏿²¡æè¿è¡ä¸çä»»å¡ |
| | | if (!statusAnalysis.IsEmptyPallet || statusAnalysis.HasActiveTasks) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | _logger.LogInformation($"æ£æµå°ç©ºæçï¼å¼å§èªå¨å¤ç - 订å: {orderNo}, æç: {palletCode}"); |
| | | |
| | | //// æ¸
çé¶åºåæ°æ® |
| | | //await CleanupZeroStockData(stockInfo.Id); |
| | | |
| | | //// æ´æ°åºåä¸»è¡¨ç¶æä¸ºç©ºæç |
| | | //await UpdateStockInfoAsEmpty(stockInfo); |
| | | |
| | | //// å¤çåºåºéå®è®°å½ |
| | | //await HandleOutStockLockRecords(orderNo, palletCode); |
| | | |
| | | //// å¤çä»»å¡ç¶æ |
| | | //await HandleTaskStatusForEmptyPallet(orderNo, palletCode); |
| | | |
| | | //// æ´æ°è®¢åæ°æ® |
| | | //await UpdateOrderDataForEmptyPallet(orderNo, palletCode); |
| | | |
| | | ////è®°å½æä½åå² |
| | | //await RecordAutoEmptyPalletOperation(orderNo, palletCode); |
| | | |
| | | _logger.LogInformation($"空æçèªå¨å¤ç宿 - 订å: {orderNo}, æç: {palletCode}"); |
| | | |
| | | return true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"èªå¨å¤ç空æç失败 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | private async Task<string> GenerateNewBarcode() |
| | | { |
| | |
| | | record.Status = (int)SplitPackageStatusEnum.å·²æ£é; |
| | | await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | private async Task<int> GenerateTaskNumber() |
| | | { |
| | | return await _dailySequenceService.GetNextSequenceAsync(); |
| | | } |
| | | |
| | | private WebResponseContent CreatePickingResponse(PickingResult result, string adjustedReason) |
| | |
| | | if (result1 != null && result1.code == 200) |
| | | { |
| | | var orderIds = inboundOrderDetails.Select(x => x.Id).Distinct().ToList(); |
| | | _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 }) |
| | | .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); |
| | | if (inboundOrder.OrderStatus == InOrderStatusEnum.å
¥åºå®æ.ObjToInt()) |
| | | { |
| | | _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" }) |
| | | .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); |
| | | } |
| | | _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 }) |
| | | .Where(it => orderIds.Contains(it.Id)).ExecuteCommand(); |
| | | } |
| | | else |
| | | { |
| | | _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = result1.message }) |
| | | .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); |
| | | _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 }) |
| | | .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand(); |
| | | } |
| | | //åºåºåä¼ MES |
| | | |
| | |
| | | |
| | | |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 1) |
| | | .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 1, Remark = "" }) |
| | | .Where(x => x.Id == outboundOrder.Id) |
| | | .ExecuteCommandAsync(); |
| | | |
| | |
| | | .Where(x => x.DocumentNo == documentNo) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | else |
| | | { |
| | | var uporderIds = outboundOrderDetails.Select(x => x.Id).Distinct().ToList(); |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 2) |
| | | .Where(x => uporderIds.Contains(x.Id)) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 2, Remark = result.message }) |
| | | .Where(x => x.Id == outboundOrder.Id) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | await _interfaceLog.Db.Updateable<Dt_InterfaceLog>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 2) |
| | | .Where(x => x.DocumentNo == documentNo) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | |
| | | public WebResponseContent GetPurchaseOrderByBarcode(string barcode) |
| | | { |
| | | try |
| | | { |
| | | Dt_InboundOrderDetail inboundOrderDetail = _stockInfoDetailService.Db.Queryable<Dt_InboundOrderDetail>().Where(x => x.Barcode == barcode && x.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()).First(); |
| | | if (inboundOrderDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°è¯¥æ¡ç {barcode}çå
¥åºæç»æè
æç»ç¶æå·²å
¥æºä»å®æ"); |
| | | } |
| | | Dt_InboundOrder inboundOrder = _inboundOrderRepository.QueryFirst(x => x.Id == inboundOrderDetail.OrderId && x.OrderStatus != InOrderStatusEnum.å
¥åºå®æ.ObjToInt()); |
| | | if (inboundOrder == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"该å
¥åºå{inboundOrder}ç¶æå·²å
¥æºä»å®æ"); |
| | | } |
| | | var resultData = new { purchaseOrderNo = inboundOrder.UpperOrderNo }; |
| | | |
| | | return WebResponseContent.Instance.OK("æ¥è¯¢éè´åæå", data: resultData); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | |
| | | if (materielGroupDTO.orderTypes == InOrderTypeEnum.ReCheck.ObjToInt()) |
| | | { |
| | | var dborder = _reCheckOrderService.Db.Queryable<Dt_ReCheckOrder>().First(x => x.OrderNo == materielGroupDTO.OrderNo); |
| | | if (dborder != null && dborder.SignSeq == 0) |
| | | if (dborder != null && (dborder.SignSeq == 0 || dborder.SignSeq == 1)) |
| | | { |
| | | return content.Error("åªææ¿å°éæ£ç»ææè½å
¥åºï¼"); |
| | | } |
| | |
| | | #endregion |
| | | } |
| | | |
| | | |
| | | |
| | | #region æ¯æç±»å®ä¹ |
| | | |
| | | public class ValidationResult<T> |
| | |
| | | public List<SplitResult> SplitResults { get; set; } = new List<SplitResult>(); |
| | | } |
| | | |
| | | public class ReturnAnalysisResult |
| | | { |
| | | public bool HasItemsToReturn { get; set; } |
| | | public bool HasRemainingLocks { get; set; } |
| | | public bool HasPalletStockGoods { get; set; } |
| | | public bool HasSplitRecords { get; set; } |
| | | public decimal RemainingLocksReturnQty { get; set; } |
| | | public decimal PalletStockReturnQty { get; set; } |
| | | public decimal SplitReturnQty { get; set; } |
| | | public decimal TotalReturnQty { get; set; } |
| | | public List<Dt_OutStockLockInfo> RemainingLocks { get; set; } = new List<Dt_OutStockLockInfo>(); |
| | | public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>(); |
| | | public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>(); |
| | | } |
| | | public class PalletStatusAnalysis |
| | | { |
| | | public string OrderNo { get; set; } |
| | |
| | | public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>(); |
| | | public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>(); |
| | | |
| | | // å·²å¤ççæ¡ç éåï¼ç¨äºé¿å
éå¤ï¼ |
| | | public HashSet<string> ProcessedBarcodes { get; set; } = new HashSet<string>(); |
| | | public List<string> AllBarcodes { get; set; } = new List<string>(); |
| | | // 空æçç¸å
³å±æ§ |
| | | public bool IsEmptyPallet { get; set; } |
| | |
| | | public bool CanReturn => HasItemsToReturn && !HasActiveTasks; |
| | | public bool CanRemove => IsEmptyPallet && !HasActiveTasks; |
| | | } |
| | | public class PickingContext |
| | | { |
| | | public string OrderNo { get; set; } |
| | | public string PalletCode { get; set; } |
| | | public string Barcode { get; set; } |
| | | public string Operator { get; set; } |
| | | public Dt_OutStockLockInfo LockInfo { get; set; } |
| | | public Dt_OutboundOrderDetail OrderDetail { get; set; } |
| | | public Dt_StockInfoDetail StockDetail { get; set; } |
| | | public decimal ActualQuantity { get; set; } |
| | | public string AdjustedReason { get; set; } |
| | | } |
| | | |
| | | public class CancelPickingContext |
| | | { |
| | | public string OrderNo { get; set; } |