| | |
| | | using WIDESEA_DTO.Inbound; |
| | | using WIDESEA_DTO.Outbound; |
| | | using WIDESEA_IBasicService; |
| | | using WIDESEA_IInboundService; |
| | | using WIDESEA_IOutboundService; |
| | | using WIDESEA_IStockService; |
| | | using WIDESEA_Model.Models; |
| | |
| | | private readonly IESSApiService _eSSApiService; |
| | | private readonly IInvokeMESService _invokeMESService; |
| | | private readonly IDailySequenceService _dailySequenceService; |
| | | |
| | | private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository; |
| | | private readonly IInboundOrderDetailService _inboundOrderDetailService; |
| | | private readonly ILogger<OutboundPickingService> _logger; |
| | | |
| | | private Dictionary<string, string> stations = new Dictionary<string, string> |
| | |
| | | public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService, |
| | | IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService, |
| | | IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService, |
| | | IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService) : base(BaseDal) |
| | | IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService, IRepository<Dt_InboundOrder> inboundOrderRepository, IInboundOrderDetailService inboundOrderDetailService) : base(BaseDal) |
| | | { |
| | | _unitOfWorkManage = unitOfWorkManage; |
| | | _stockInfoService = stockInfoService; |
| | |
| | | _logger = logger; |
| | | _invokeMESService = invokeMESService; |
| | | _dailySequenceService = dailySequenceService; |
| | | _inboundOrderRepository = inboundOrderRepository; |
| | | _inboundOrderDetailService = inboundOrderDetailService; |
| | | } |
| | | |
| | | // è·åæªæ£éå表 |
| | |
| | | try |
| | | { |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | // 1. åç½®éªè¯åä¸å¡æ£æ¥ |
| | | |
| | | var validationResult = await ValidatePickingRequest(orderNo, palletCode, barcode); |
| | | if (!validationResult.IsValid) |
| | | return WebResponseContent.Instance.Error(validationResult.ErrorMessage); |
| | | |
| | | var (lockInfo, orderDetail, stockDetail) = validationResult.Data; |
| | | |
| | | // 2. 计ç®å®é
æ£éæ°é |
| | | // 计ç®å®é
æ£éæ°é |
| | | var quantityResult = await CalculateActualPickingQuantity(lockInfo, orderDetail, stockDetail); |
| | | if (!quantityResult.IsValid) |
| | | return WebResponseContent.Instance.Error(quantityResult.ErrorMessage); |
| | | |
| | | var (actualQty, adjustedReason) = quantityResult.Data; |
| | | |
| | | // 3. æ§è¡åæ£é»è¾ |
| | | var overPickingValidation = await ValidateOverPicking(orderDetail.Id, actualQty); |
| | | if (!overPickingValidation.IsValid) |
| | | { |
| | | return WebResponseContent.Instance.Error(overPickingValidation.ErrorMessage); |
| | | } |
| | | |
| | | // æ§è¡åæ£é»è¾ |
| | | var pickingResult = await ExecutePickingLogic(lockInfo, orderDetail, stockDetail, orderNo, palletCode, barcode, actualQty); |
| | | |
| | | // 4. æ´æ°ç¸å
³æ°æ® |
| | | // æ´æ°ç¸å
³æ°æ® |
| | | await UpdateOrderRelatedData(orderDetail.Id, pickingResult.ActualPickedQty, orderNo); |
| | | |
| | | // 5. è®°å½æä½åå² |
| | | // è®°å½æä½åå² |
| | | await RecordPickingHistory(pickingResult, orderNo, palletCode); |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | |
| | | decimal remainingOrderQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity; |
| | | decimal stockQuantity = stockDetail.StockQuantity; |
| | | |
| | | if (plannedQty <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"è®¡åæ£éæ°éå¿
须大äº0ï¼å½å: {plannedQty}"); |
| | | } |
| | | |
| | | if (remainingOrderQty <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"订åå©ä½éæ±æ°éå¿
须大äº0ï¼å½å: {remainingOrderQty}"); |
| | | } |
| | | |
| | | if (stockQuantity <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"åºåæ°éå¿
须大äº0ï¼å½å: {stockQuantity}"); |
| | | } |
| | | // ä¸éæ£æ¥ï¼åæå°å¼ |
| | | decimal actualQty = plannedQty; |
| | | string adjustedReason = null; |
| | | |
| | | // æ£æ¥1ï¼è®¢åæ°ééå¶ |
| | | if (plannedQty > remainingOrderQty && remainingOrderQty > 0) |
| | | if (plannedQty > remainingOrderQty) |
| | | { |
| | | actualQty = remainingOrderQty; |
| | | adjustedReason = $"è®¢åæ°ééå¶ï¼ä»{plannedQty}è°æ´ä¸º{actualQty}"; |
| | | } |
| | | |
| | | // æ£æ¥2ï¼åºåæ°ééå¶ |
| | | if (actualQty > stockQuantity) |
| | | { |
| | | actualQty = stockQuantity; |
| | |
| | | ? $"{adjustedReason}ï¼åºåæ°ééå¶ï¼è¿ä¸æ¥è°æ´ä¸º{actualQty}" |
| | | : $"åºåæ°ééå¶ï¼ä»{plannedQty}è°æ´ä¸º{actualQty}"; |
| | | } |
| | | |
| | | // æ£æ¥3ï¼å®é
坿£éæ°éå¿
须大äº0 |
| | | if (actualQty <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"æ æ³åæ£ï¼è®¡åæ°é{plannedQty}ï¼å©ä½è®¢å{remainingOrderQty}ï¼åºå{stockQuantity}"); |
| | | return ValidationResult<(decimal, string)>.Error($"æ æ³åæ£ï¼è®¡ç®åçå®é
æ°é为{actualQty}"); |
| | | } |
| | | decimal projectedOverOut = orderDetail.OverOutQuantity + actualQty; |
| | | if (projectedOverOut > orderDetail.NeedOutQuantity) |
| | | { |
| | | // 妿ä¼è¶
æ£ï¼è°æ´ä¸ºåå¥½æ»¡è¶³éæ±çæ°é |
| | | actualQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity; |
| | | adjustedReason = adjustedReason != null |
| | | ? $"{adjustedReason}ï¼é²è¶
æ£éå¶ï¼æç»è°æ´ä¸º{actualQty}" |
| | | : $"é²è¶
æ£éå¶ï¼ä»{plannedQty}è°æ´ä¸º{actualQty}"; |
| | | } |
| | | |
| | | if (adjustedReason != null) |
| | | { |
| | |
| | | return ValidationResult<(decimal, string)>.Success((actualQty, adjustedReason)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä¸é¨éªè¯æ¯å¦ä¼åçè¶
æ£ |
| | | /// </summary> |
| | | private async Task<ValidationResult<bool>> ValidateOverPicking(int orderDetailId, decimal pickingQty) |
| | | { |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == orderDetailId); |
| | | |
| | | if (orderDetail == null) |
| | | return ValidationResult<bool>.Error("æªæ¾å°è®¢åæç»"); |
| | | |
| | | decimal projectedOverOut = orderDetail.OverOutQuantity + pickingQty; |
| | | |
| | | if (projectedOverOut > orderDetail.NeedOutQuantity) |
| | | { |
| | | return ValidationResult<bool>.Error( |
| | | $"忣åå°å¯¼è´è¶
æ£ï¼å½åå·²åºåº{orderDetail.OverOutQuantity}ï¼æ¬æ¬¡åæ£{pickingQty}ï¼å计{projectedOverOut}ï¼è¶
è¿éæ±{orderDetail.NeedOutQuantity}"); |
| | | } |
| | | |
| | | return ValidationResult<bool>.Success(true); |
| | | } |
| | | private async Task<PickingResult> ExecutePickingLogic( |
| | | Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail, Dt_StockInfoDetail stockDetail, |
| | | string orderNo, string palletCode, string barcode, decimal actualQty) |
| | |
| | | decimal newOverOutQuantity = currentOrderDetail.OverOutQuantity + pickedQty; |
| | | decimal newPickedQty = currentOrderDetail.PickedQty + pickedQty; |
| | | |
| | | // æç»æ£æ¥ï¼ç¡®ä¿ä¸ä¼è¶
è¿è®¢åéæ±æ°é |
| | | if (newOverOutQuantity > currentOrderDetail.NeedOutQuantity) |
| | | { |
| | | throw new Exception($"忣åå°å¯¼è´å·²åºåºæ°é({newOverOutQuantity})è¶
è¿è®¢åéæ±æ°é({currentOrderDetail.NeedOutQuantity})"); |
| | | |
| | | _logger.LogError($"é²è¶
æ£æ£æ¥å¤±è´¥ - OrderDetailId: {orderDetailId}, å·²åºåº: {newOverOutQuantity}, éæ±: {currentOrderDetail.NeedOutQuantity}, æ¬æ¬¡åæ£: {pickedQty}"); |
| | | |
| | | |
| | | decimal adjustedQty = currentOrderDetail.NeedOutQuantity - currentOrderDetail.OverOutQuantity; |
| | | |
| | | if (adjustedQty > 0) |
| | | { |
| | | _logger.LogWarning($"èªå¨è°æ´åæ£æ°é鲿¢è¶
æ£ï¼ä»{pickedQty}è°æ´ä¸º{adjustedQty}"); |
| | | newOverOutQuantity = currentOrderDetail.NeedOutQuantity; |
| | | newPickedQty = currentOrderDetail.PickedQty + adjustedQty; |
| | | } |
| | | else |
| | | { |
| | | throw new Exception($"忣åå°å¯¼è´å·²åºåºæ°é({newOverOutQuantity})è¶
è¿è®¢åéæ±æ°é({currentOrderDetail.NeedOutQuantity})ï¼ä¸æ æ³èªå¨è°æ´"); |
| | | } |
| | | } |
| | | |
| | | // æ´æ°è®¢åæç» |
| | |
| | | if (pickingRecord == null) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("æªæ¾å°å¯¹åºçæ£éè®°å½"); |
| | | |
| | | if (pickingRecord.PickQuantity <= 0) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"æ£éè®°å½æ°éæ æ: {pickingRecord.PickQuantity}"); |
| | | } |
| | | // æ¥æ¾éå®ä¿¡æ¯ |
| | | var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.Id == pickingRecord.OutStockLockId) |
| | |
| | | |
| | | if (lockInfo == null) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("æªæ¾å°å¯¹åºçåºåºéå®ä¿¡æ¯"); |
| | | |
| | | |
| | | if (lockInfo.PickedQty < pickingRecord.PickQuantity) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error( |
| | | $"åæ¶æ°é({pickingRecord.PickQuantity})è¶
è¿éå®ä¿¡æ¯çå·²æ£éæ°é({lockInfo.PickedQty})"); |
| | | } |
| | | // æ£æ¥ç¶ææ¯å¦å
è®¸åæ¶ |
| | | if (lockInfo.Status != (int)OutLockStockStatusEnum.æ£é宿) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("å½åç¶æä¸å
è®¸åæ¶åæ£"); |
| | | |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == barcode && it.StockId == pickingRecord.StockId) |
| | | .FirstAsync(); |
| | | var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().FirstAsync(x => x.OrderNo == orderNo); |
| | | |
| | | if (order?.OrderStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("订åå·²åºåºå®æï¼ä¸å
è®¸åæ¶åæ£"); |
| | | |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().FirstAsync(x => x.Id == pickingRecord.OrderDetailId); |
| | | |
| | | if (orderDetail == null) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"æªæ¾å°è®¢åæç»ï¼ID: {pickingRecord.OrderDetailId}"); |
| | | |
| | | // æ£æ¥è®¢åæç»çå·²æ£éæ°éæ¯å¦è¶³å¤åæ¶ |
| | | if (orderDetail.PickedQty < pickingRecord.PickQuantity) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"åæ¶æ°é({pickingRecord.PickQuantity})è¶
è¿è®¢åæç»çå·²æ£éæ°é({orderDetail.PickedQty})"); |
| | | } |
| | | |
| | | // æ£æ¥è®¢åæç»çå·²åºåºæ°éæ¯å¦è¶³å¤åæ¶ |
| | | if (orderDetail.OverOutQuantity < pickingRecord.PickQuantity) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"åæ¶æ°é({pickingRecord.PickQuantity})è¶
è¿è®¢åæç»çå·²åºåºæ°é({orderDetail.OverOutQuantity})"); |
| | | } |
| | | |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>().FirstAsync(it => it.Barcode == barcode && it.StockId == pickingRecord.StockId); |
| | | |
| | | if (stockDetail != null) |
| | | { |
| | |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"æ¡ç {barcode}å·²ç»ååºï¼ä¸è½åæ¶åæ£"); |
| | | } |
| | | } |
| | | |
| | | // æ£æ¥è®¢åç¶æ |
| | | var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .FirstAsync(); |
| | | |
| | | if (order?.OrderStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("订åå·²åºåºå®æï¼ä¸å
è®¸åæ¶åæ£"); |
| | | |
| | | // è·å订åæç» |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == pickingRecord.OrderDetailId); |
| | | |
| | | if (orderDetail == null) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"æªæ¾å°è®¢åæç»ï¼ID: {pickingRecord.OrderDetailId}"); |
| | | |
| | | } |
| | | |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Success((pickingRecord, lockInfo, orderDetail)); |
| | | } |
| | | /// <summary> |
| | |
| | | await UpdateOrderDetailsOnReturn(analysis.RemainingLocks); |
| | | } |
| | | |
| | | // æ
åµ2ï¼å¤çæçä¸å
¶ä»åºåè´§ç© |
| | | // å¤çæçä¸å
¶ä»åºåè´§ç© |
| | | if (analysis.HasPalletStockGoods) |
| | | { |
| | | await HandlePalletStockGoodsReturn(analysis.PalletStockGoods); |
| | | } |
| | | |
| | | // æ
åµ3ï¼å¤çæå
è®°å½ |
| | | // å¤çæå
è®°å½ |
| | | if (analysis.HasSplitRecords) |
| | | { |
| | | await HandleSplitRecordsReturn(analysis.SplitRecords, orderNo, palletCode); |
| | |
| | | } |
| | | return WebResponseContent.Instance.OK("æ£é确认æå", new { SplitResults = new List<SplitResult>() }); |
| | | } |
| | | |
| | | |
| | | |
| | | #region èæåºå
¥åº |
| | | public WebResponseContent GetAvailablePurchaseOrders() |
| | | { |
| | | List<Dt_InboundOrder> InOders = _inboundOrderRepository.QueryData().Where(x => x.OrderStatus != InOrderStatusEnum.å
¥åºå®æ.ObjToInt()).ToList(); |
| | | List<string> InOderCodes = InOders.Select(x => x.UpperOrderNo).ToList(); |
| | | return WebResponseContent.Instance.OK("æå",data: InOderCodes); |
| | | } |
| | | |
| | | public WebResponseContent GetAvailablePickingOrders() |
| | | { |
| | | List<Dt_OutboundOrder> outOders = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().Where(x => x.OrderStatus != OutOrderStatusEnum.åºåºå®æ.ObjToInt()).ToList(); |
| | | |
| | | List<string> outOderCodes = outOders.Select(x => x.UpperOrderNo).ToList(); |
| | | return WebResponseContent.Instance.OK("æå", data: outOderCodes); |
| | | |
| | | } |
| | | public WebResponseContent BarcodeValidate(NoStockOutModel noStockOut) |
| | | { |
| | | try |
| | | { |
| | | Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.å
¥åºå®æ.ObjToInt()).Includes(x => x.Details).First(); |
| | | if(inboundOrder == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°éè´åï¼{noStockOut.inOder}"); |
| | | } |
| | | var matchedDetail = inboundOrder.Details.FirstOrDefault(detail => detail.Barcode == noStockOut.barCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()); |
| | | |
| | | if (matchedDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"å¨éè´å {noStockOut.inOder} 䏿ªæ¾å°æ¡ç 为 {noStockOut.barCode} çæç»ã"); |
| | | } |
| | | matchedDetail.NoStockOutQty = 0; |
| | | |
| | | Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.åºåºå®æ.ObjToInt()).Includes(x => x.Details).First(); |
| | | if (outboundOrder == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°åºåºåï¼{noStockOut.inOder}"); |
| | | } |
| | | var matchedCode = outboundOrder.Details.FirstOrDefault(detail => detail.MaterielCode == matchedDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()); |
| | | |
| | | if (matchedCode == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"å¨åºåºåçç©æç¼ç 䏿ªæ¾å°ä¸éè´åä¸ç{matchedDetail.MaterielCode} 对åºçç©æã"); |
| | | } |
| | | matchedCode.NoStockOutQty = 0; |
| | | |
| | | //å©ä½å
¥åºæ°éå³èæåºå
¥åºå©ä½å¯åºæ°é |
| | | decimal outQuantity = matchedDetail.OrderQuantity - matchedDetail.ReceiptQuantity; |
| | | if(outQuantity == 0) |
| | | { |
| | | return WebResponseContent.Instance.Error($"该éè´åä¸çæ¡ç 对åºçå¯åºæ°é为0"); |
| | | } |
| | | if (matchedCode.OrderQuantity < outQuantity) |
| | | { |
| | | return WebResponseContent.Instance.Error($"该éè´åä¸çæ¡ç 对åºçå¯åºæ°éè¶
åºåºåºååºåºæ°é{matchedDetail.OrderQuantity - matchedCode.OrderQuantity},䏿»¡è¶³æ´å
åºåº"); |
| | | } |
| | | //åæ®åºåºé宿°é |
| | | matchedDetail.NoStockOutQty += outQuantity; |
| | | matchedCode.NoStockOutQty += outQuantity; |
| | | |
| | | if ((matchedCode.LockQuantity + matchedCode.NoStockOutQty) > matchedCode.OrderQuantity) |
| | | { |
| | | return WebResponseContent.Instance.Error($"åºåºåæç»æ°é溢åº{matchedCode.LockQuantity - matchedCode.OrderQuantity}"); |
| | | } |
| | | matchedDetail.OrderDetailStatus = OrderDetailStatusEnum.Inbounding.ObjToInt(); |
| | | matchedCode.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); |
| | | |
| | | _unitOfWorkManage.BeginTran(); |
| | | _inboundOrderDetailService.UpdateData(matchedDetail); |
| | | _outboundOrderDetailService.UpdateData(matchedCode); |
| | | _unitOfWorkManage.CommitTran(); |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | catch(Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | |
| | | |
| | | public WebResponseContent DeleteBarcode(NoStockOutModel noStockOut) |
| | | { |
| | | try |
| | | { |
| | | Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.å
¥åºå®æ.ObjToInt()).Includes(x => x.Details).First(); |
| | | if (inboundOrder == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°éè´åï¼{noStockOut.inOder}"); |
| | | } |
| | | var matchedDetail = inboundOrder.Details.FirstOrDefault(detail => detail.Barcode == noStockOut.barCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()); |
| | | |
| | | if (matchedDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"å¨éè´å {noStockOut.inOder} 䏿ªæ¾å°æ¡ç 为 {noStockOut.barCode} çæç»ã"); |
| | | } |
| | | matchedDetail.NoStockOutQty = 0; |
| | | |
| | | Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.åºåºå®æ.ObjToInt()).Includes(x => x.Details).First(); |
| | | if (outboundOrder == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°åºåºåï¼{noStockOut.inOder}"); |
| | | } |
| | | var matchedCode = outboundOrder.Details.FirstOrDefault(detail => detail.MaterielCode == matchedDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()); |
| | | |
| | | if (matchedCode == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"å¨åºåºåçç©æç¼ç 䏿ªæ¾å°ä¸éè´åä¸ç{matchedDetail.MaterielCode} 对åºçç©æã"); |
| | | } |
| | | matchedCode.NoStockOutQty = 0; |
| | | _unitOfWorkManage.BeginTran(); |
| | | _inboundOrderDetailService.UpdateData(matchedDetail); |
| | | _outboundOrderDetailService.UpdateData(matchedCode); |
| | | _unitOfWorkManage.CommitTran(); |
| | | return WebResponseContent.Instance.OK(); |
| | | |
| | | } |
| | | catch(Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | |
| | | public WebResponseContent NoStockOutSubmit(NoStockOutSubmit noStockOutSubmit) |
| | | { |
| | | try |
| | | { |
| | | Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOutSubmit.InOderSubmit && x.OrderStatus != InOrderStatusEnum.å
¥åºå®æ.ObjToInt()).Includes(x => x.Details).First(); |
| | | if (inboundOrder == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°éè´åï¼{noStockOutSubmit.InOderSubmit}"); |
| | | } |
| | | Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOutSubmit.OutOderSubmit && x.OrderStatus != OutOrderStatusEnum.åºåºå®æ.ObjToInt()).Includes(x => x.Details).First(); |
| | | if (outboundOrder == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°åºåºåï¼{noStockOutSubmit.OutOderSubmit}"); |
| | | } |
| | | List<Dt_InboundOrderDetail> inboundOrderDetails = new List<Dt_InboundOrderDetail>(); |
| | | List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>(); |
| | | foreach (var BarCode in noStockOutSubmit.BarCodeSubmit) |
| | | { |
| | | var inboundOrderDetail = inboundOrder.Details.FirstOrDefault(detail => detail.Barcode == BarCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()); |
| | | |
| | | if(inboundOrderDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"å¨éè´å {noStockOutSubmit.InOderSubmit} 䏿ªæ¾å°æ¡ç 为 {BarCode} çæç»ã"); |
| | | } |
| | | var outboundOrderDetail = outboundOrder.Details.FirstOrDefault(detail => detail.MaterielCode == inboundOrderDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()); |
| | | |
| | | if (outboundOrderDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"å¨åºåºåçç©æç¼ç 䏿ªæ¾å°ä¸éè´åä¸ç{inboundOrderDetail.MaterielCode} 对åºçç©æã"); |
| | | } |
| | | inboundOrderDetail.ReceiptQuantity += inboundOrderDetail.NoStockOutQty; |
| | | inboundOrderDetail.OverInQuantity = inboundOrderDetail.ReceiptQuantity; |
| | | inboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); |
| | | inboundOrderDetails.Add(inboundOrderDetail); |
| | | |
| | | outboundOrderDetail.LockQuantity += outboundOrderDetail.NoStockOutQty; |
| | | outboundOrderDetail.OverOutQuantity = outboundOrderDetail.LockQuantity; |
| | | if(outboundOrderDetail.OrderQuantity == outboundOrderDetail.OverOutQuantity) |
| | | { |
| | | outboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); |
| | | } |
| | | outboundOrderDetails.Add(outboundOrderDetail); |
| | | |
| | | } |
| | | //夿å
¥åºåæ®æç»æ¯å¦å
¨é¨æ¯å®æç¶æ |
| | | bool inoderOver = inboundOrder.Details.Count() == inboundOrder.Details.Select(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); |
| | | if (inoderOver) |
| | | { |
| | | inboundOrder.OrderStatus = InOrderStatusEnum.å
¥åºå®æ.ObjToInt(); |
| | | } |
| | | //夿åºåºåæ®æç»æ¯å¦å
¨é¨æ¯å®æç¶æ |
| | | bool outOderOver = outboundOrder.Details.Count() == outboundOrder.Details.Select(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); |
| | | if (outOderOver) |
| | | { |
| | | outboundOrder.OrderStatus = OutOrderStatusEnum.åºåºå®æ.ObjToInt(); |
| | | } |
| | | //æ°æ®å¤ç |
| | | _unitOfWorkManage.BeginTran(); |
| | | _inboundOrderDetailService.UpdateData(inboundOrderDetails); |
| | | _outboundOrderDetailService.UpdateData(outboundOrderDetails); |
| | | _inboundOrderRepository.UpdateData(inboundOrder); |
| | | _outboundOrderService.UpdateData(outboundOrder); |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | catch(Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | |
| | | #endregion |
| | | } |
| | | |
| | | |
| | | |
| | | #region æ¯æç±»å®ä¹ |
| | | |
| | | public class ValidationResult<T> |