| | |
| | | using WIDESEA_Common.AllocateEnum; |
| | | using WIDESEA_Model.Models.Basic; |
| | | using WIDESEA_IOutboundService; |
| | | using WIDESEA_DTO.CalcOut; |
| | | using Newtonsoft.Json.Serialization; |
| | | using Newtonsoft.Json; |
| | | |
| | | namespace WIDESEA_InboundService |
| | | { |
| | |
| | | private readonly IRepository<Dt_InboundOrderDetail> _inboundOrderDetailRepository; |
| | | private readonly IRepository<Dt_OutboundOrderDetail> _outboundOrderDetailRepository; |
| | | private readonly IOutboundPickingService _outboundPickingService; |
| | | public TakeStockOrderService(IRepository<Dt_TakeStockOrder> BaseDal, IUnitOfWorkManage unitOfWorkManage,IRepository<Dt_TakeStockOrder> takeStockOrder,IRepository<Dt_StockInfo> stockInfoRepository,IRepository<Dt_TakeStockOrderDetail> takeStockOrderDetail,IRepository<Dt_Task> taskRepository,ILocationInfoService locationInfoService, IRepository<Dt_InboundOrder> inboundOrderRepository,IRepository<Dt_OutboundOrder> outboundOrderRepository,IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_OutboundOrderDetail> outboundOrderDetailRepository, IOutboundPickingService outboundPickingService) : base(BaseDal) |
| | | private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository; |
| | | private readonly IOutboundService _outboundService; |
| | | private readonly IFeedbackMesService _feedbackMesService; |
| | | public TakeStockOrderService(IRepository<Dt_TakeStockOrder> BaseDal, IUnitOfWorkManage unitOfWorkManage,IRepository<Dt_TakeStockOrder> takeStockOrder,IRepository<Dt_StockInfo> stockInfoRepository,IRepository<Dt_TakeStockOrderDetail> takeStockOrderDetail,IRepository<Dt_Task> taskRepository,ILocationInfoService locationInfoService, IRepository<Dt_InboundOrder> inboundOrderRepository,IRepository<Dt_OutboundOrder> outboundOrderRepository,IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_OutboundOrderDetail> outboundOrderDetailRepository, IOutboundPickingService outboundPickingService, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IOutboundService outboundService,IFeedbackMesService feedbackMesService) : base(BaseDal) |
| | | { |
| | | _unitOfWorkManage = unitOfWorkManage; |
| | | _takeStockOrder = takeStockOrder; |
| | |
| | | _inboundOrderDetailRepository = inboundOrderDetailRepository; |
| | | _outboundOrderDetailRepository = outboundOrderDetailRepository; |
| | | _outboundPickingService = outboundPickingService; |
| | | _stockInfoDetailRepository = stockInfoDetailRepository; |
| | | _outboundService = outboundService; |
| | | _feedbackMesService = feedbackMesService; |
| | | } |
| | | |
| | | public WebResponseContent ValidateBoxNo(string orderNo, string boxNo) |
| | |
| | | Unit = stockInfoDetail.Unit, |
| | | SysQty = completeStockTakeDTO.stockQuantity, |
| | | Qty = completeStockTakeDTO.actualQuantity, |
| | | Remark = completeStockTakeDTO.stockQuantity - completeStockTakeDTO.actualQuantity >= 0 ? "çäº" : "çç", |
| | | Remark = completeStockTakeDTO.actualQuantity - completeStockTakeDTO.stockQuantity >= 0 ? "çç" : "çäº", |
| | | barcode = completeStockTakeDTO.barcode, |
| | | WarehouseCode = stockInfoDetail.WarehouseCode ?? "", |
| | | FactoryArea = stockInfoDetail.FactoryArea, |
| | | SupplyCode = stockInfoDetail.SupplyCode ?? "", |
| | | TakeStockNo = takeStockOrder.OrderNo, |
| | | DifferenceQty = completeStockTakeDTO.stockQuantity - completeStockTakeDTO.actualQuantity |
| | | DifferenceQty = completeStockTakeDTO.actualQuantity - completeStockTakeDTO.stockQuantity |
| | | |
| | | }; |
| | | foreach (var item in stockInfo.Details) |
| | |
| | | { |
| | | var matchedDetails = outboundOrder.Details |
| | | .Where(detail => !string.IsNullOrWhiteSpace(detail.MaterielCode) |
| | | && detail.MaterielCode == takeStockOrderDetail.MaterielCode) |
| | | && detail.MaterielCode == takeStockOrderDetail.MaterielCode && detail.OrderQuantity-detail.MoveQty-detail.OverOutQuantity>0) |
| | | .WhereIF(!string.IsNullOrWhiteSpace(takeStockOrderDetail.FactoryArea), |
| | | detail => !string.IsNullOrWhiteSpace(outboundOrder.FactoryArea) |
| | | && outboundOrder.FactoryArea == takeStockOrderDetail.FactoryArea) |
| | |
| | | |
| | | public WebResponseContent DocumentReconciliation(int orderId, int id) |
| | | { |
| | | WebResponseContent webResponseContent = new WebResponseContent(); |
| | | try |
| | | { |
| | | Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x => x.Id == id); |
| | |
| | | } |
| | | if(takeStockOrderDetail.Remark == "çç") |
| | | { |
| | | Dt_InboundOrderDetail inboundOrderDetail = _inboundOrderDetailRepository.QueryFirst(x => x.OrderId == orderId); |
| | | Dt_InboundOrderDetail inboundOrderDetail = _inboundOrderDetailRepository.QueryFirst(x => x.Id == orderId); |
| | | if(inboundOrderDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error("æªæ¾å°éæ©çææ¶å¹³è´¦åæ®"); |
| | | } |
| | | Dt_InboundOrder inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().Where(x=>x.Id == orderId).Includes(x=>x.Details).First(); |
| | | Dt_InboundOrder inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().Where(x=>x.Id == inboundOrderDetail.OrderId).Includes(x=>x.Details).First(); |
| | | Dt_StockInfo stockInfo = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x=>x.PalletCode == takeStockOrderDetail.TakePalletCode && x.StockStatus == StockStatusEmun.çç¹åºå宿.ObjToInt()).Includes(x=>x.Details).First(); |
| | | if(stockInfo== null) |
| | | { |
| | |
| | | { |
| | | inboundOrder.OrderStatus = InOrderStatusEnum.å
¥åºä¸.ObjToInt(); |
| | | } |
| | | takeStockOrderDetail.DifferenceQty += inboundOrderDetail.OrderQuantity; |
| | | takeStockOrderDetail.DifferenceQty -= inboundOrderDetail.OrderQuantity; |
| | | if(takeStockOrderDetail.DifferenceQty > 0) |
| | | { |
| | | return WebResponseContent.Instance.Error("è¯¥ææ¶åæ®æç»æ¡ç æ°é大äºå¾
平账æ°éï¼è¯·å¦éå
¶ä»åæ®å¹³è´¦"); |
| | | takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.ææ¶æå平账å¤çä¸.ObjToInt(); |
| | | } |
| | | else if (takeStockOrderDetail.DifferenceQty == 0) |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.ææ¶æå平账å¤çä¸.ObjToInt(); |
| | | return WebResponseContent.Instance.Error("è¯¥ææ¶åæ®æç»æ¡ç æ°é大äºå¾
平账æ°éï¼è¯·å¦éå
¶ä»åæ®å¹³è´¦"); |
| | | } |
| | | |
| | | _unitOfWorkManage.BeginTran(); |
| | |
| | | _unitOfWorkManage.CommitTran(); |
| | | List<string> barcodes = new List<string>(); |
| | | barcodes.Add(inboundOrderDetail.Barcode); |
| | | _outboundPickingService.NoStockOutBatchInOrderFeedbackToMes(orderId, barcodes); |
| | | _outboundPickingService.NoStockOutBatchInOrderFeedbackToMes(inboundOrder.Id, barcodes); |
| | | |
| | | |
| | | } |
| | | else |
| | | { |
| | | |
| | | Dt_OutboundOrderDetail outboundOrderDetail = _outboundOrderDetailRepository.QueryFirst(x => x.Id == orderId); |
| | | if (outboundOrderDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error("æªæ¾å°éæ©çæåå¹³è´¦åæ®"); |
| | | } |
| | | Dt_OutboundOrder outboundOrder = _outboundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => x.Id == outboundOrderDetail.OrderId).Includes(x => x.Details).First(); |
| | | Dt_StockInfo stockInfo = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletCode == takeStockOrderDetail.TakePalletCode && x.StockStatus == StockStatusEmun.çç¹åºå宿.ObjToInt()).Includes(x => x.Details).First(); |
| | | if (stockInfo == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"çç¹æç{takeStockOrderDetail.TakePalletCode}çåºåä¿¡æ¯æªæ¾å°ï¼ææçç¶æä¸æ£ç¡®"); |
| | | } |
| | | if(outboundOrderDetail.OrderQuantity + takeStockOrderDetail.DifferenceQty > 0) |
| | | { |
| | | return WebResponseContent.Instance.Error("该æååæ®æç»åææ°é大äºå¾
平账æ°éï¼è¯·å¦éå
¶ä»åæ®å¹³è´¦"); |
| | | } |
| | | else if(outboundOrderDetail.OrderQuantity + takeStockOrderDetail.DifferenceQty < 0) |
| | | { |
| | | takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.ææ¶æå平账å¤çä¸.ObjToInt(); |
| | | } |
| | | else |
| | | { |
| | | takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.ææ¶æå平账å¤ç.ObjToInt(); |
| | | } |
| | | OutboundCompleteRequestDTO request = new OutboundCompleteRequestDTO() |
| | | { |
| | | OrderNo = outboundOrder.OrderNo, |
| | | PalletCode = stockInfo.PalletCode, |
| | | Barcode = takeStockOrderDetail.barcode, |
| | | Operator = App.User.UserName |
| | | }; |
| | | decimal stoQty = takeStockOrderDetail.SysQty; |
| | | webResponseContent = CompleteOutboundWithBarcode(request, stoQty, orderId); |
| | | takeStockOrderDetail.DifferenceQty = 0; |
| | | _takeStockOrderDetail.UpdateData(takeStockOrderDetail); |
| | | } |
| | | return WebResponseContent.Instance.OK(); |
| | | return WebResponseContent.Instance.OK(data: webResponseContent); |
| | | } |
| | | catch(Exception ex) |
| | | { |
| | |
| | | |
| | | } |
| | | } |
| | | public WebResponseContent CompleteOutboundWithBarcode(OutboundCompleteRequestDTO request ,decimal stoQty, int orderDetailId) |
| | | { |
| | | WebResponseContent content = WebResponseContent.Instance; |
| | | |
| | | OutboundCompleteResponseDTO response = new(); |
| | | try |
| | | { |
| | | // 1. æ ¹æ®æçå·æ¥æ¾åºåä¿¡æ¯ |
| | | Dt_StockInfo stockInfo = _stockInfoRepository.QueryFirst(x => x.PalletCode == request.PalletCode); |
| | | if (stockInfo == null) |
| | | { |
| | | response.Success = false; |
| | | response.Message = $"æçå· {request.PalletCode} 对åºçåºåä¸åå¨"; |
| | | return WebResponseContent.Instance.Error($"æçå· {request.PalletCode} 对åºçåºåä¸åå¨"); |
| | | } |
| | | |
| | | // 2. æ ¹æ®æ¡ç æ¥æ¾åºåæç» |
| | | Dt_StockInfoDetail stockDetail = _stockInfoDetailRepository.QueryFirst(x => x.Barcode == request.Barcode); |
| | | if (stockDetail == null) |
| | | { |
| | | response.Success = false; |
| | | response.Message = $"æ¡ç {request.Barcode} 对åºçåºåæç»ä¸åå¨"; |
| | | return WebResponseContent.Instance.Error($"æ¡ç {request.Barcode} 对åºçåºåæç»ä¸åå¨"); |
| | | } |
| | | |
| | | // 3. éªè¯åºåæç»ä¸æçæ¯å¦å¹é
|
| | | if (stockDetail.StockId != stockInfo.Id) |
| | | { |
| | | response.Success = false; |
| | | response.Message = $"æ¡ç {request.Barcode} ä¸å±äºæçå· {request.PalletCode} çåºåæç»"; |
| | | return WebResponseContent.Instance.Error($"æ¡ç {request.Barcode} ä¸å±äºæçå· {request.PalletCode} çåºåæç»"); |
| | | } |
| | | |
| | | // 4. æ¥æ¾åºåºåä¿¡æ¯ |
| | | Dt_OutboundOrder outboundOrder = _outboundOrderRepository.QueryFirst(o => o.OrderNo == request.OrderNo); |
| | | if (outboundOrder == null) |
| | | { |
| | | response.Success = false; |
| | | response.Message = $"åºåºå {request.OrderNo} ä¸åå¨"; |
| | | return WebResponseContent.Instance.Error($"åºåºå {request.OrderNo} ä¸åå¨"); |
| | | } |
| | | |
| | | Dt_OutboundOrderDetail outboundOrderDetail = _outboundOrderDetailRepository.QueryFirst(x => x.Id == orderDetailId); |
| | | if (outboundOrderDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error("æªæ¾å°åºåºåæç»"); |
| | | } |
| | | // å®é
åºåºé |
| | | decimal actualOutboundQuantity = outboundOrderDetail.OrderQuantity; |
| | | |
| | | |
| | | // 8. 夿æ¯å¦éè¦æå
ï¼å½åºåºæ°éå°äºåºåæ°éæ¶éè¦æå
ï¼ |
| | | bool isUnpacked = outboundOrderDetail.OrderQuantity < stockDetail.StockQuantity; |
| | | List<MaterialCodeReturnDTO> returnDTOs = new List<MaterialCodeReturnDTO>(); |
| | | string newBarcode = string.Empty; |
| | | // 9. å¼å¯äºå¡ |
| | | _unitOfWorkManage.BeginTran(); |
| | | try |
| | | { |
| | | decimal beforeQuantity = stockDetail.StockQuantity; // åå§åºåé |
| | | |
| | | Dt_AllocateMaterialInfo allocateMaterialInfo = new Dt_AllocateMaterialInfo(); |
| | | |
| | | // æ ¹æ®æ¯å¦æå
æ§è¡ä¸åçæä½ |
| | | if (isUnpacked) |
| | | { |
| | | (string NewBarcode, List<MaterialCodeReturnDTO> MaterialCodeReturnDTOs) result = _outboundService.PerformUnpackOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, 0, outboundOrder.Id, outboundOrder.OrderNo); |
| | | |
| | | returnDTOs = result.MaterialCodeReturnDTOs; |
| | | newBarcode = result.NewBarcode; |
| | | |
| | | MaterialCodeReturnDTO returnDTO = returnDTOs.First(x => x.Barcode == newBarcode); |
| | | |
| | | if (outboundOrder.OrderType != 0) |
| | | { |
| | | allocateMaterialInfo = new Dt_AllocateMaterialInfo() |
| | | { |
| | | Barcode = returnDTO.Barcode, |
| | | BatchNo = returnDTO.BatchNo, |
| | | FactoryArea = returnDTO.FactoryArea, |
| | | MaterialCode = returnDTO.MaterialCode, |
| | | MaterialName = returnDTO.MaterialName, |
| | | OrderId = outboundOrder.Id, |
| | | OrderNo = outboundOrder.OrderNo, |
| | | Quantity = returnDTO.Quantity, |
| | | SupplyCode = returnDTO.SuplierCode, |
| | | Unit = stockDetail.Unit |
| | | }; |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | _outboundService.PerformFullOutboundOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, 0); |
| | | |
| | | if (outboundOrder.OrderType != 0) |
| | | { |
| | | allocateMaterialInfo = new Dt_AllocateMaterialInfo() |
| | | { |
| | | Barcode = stockDetail.Barcode, |
| | | BatchNo = stockDetail.BatchNo, |
| | | FactoryArea = stockDetail.FactoryArea, |
| | | MaterialCode = stockDetail.MaterielCode, |
| | | MaterialName = stockDetail.MaterielName, |
| | | OrderId = outboundOrder.Id, |
| | | OrderNo = outboundOrder.OrderNo, |
| | | Quantity = stockDetail.StockQuantity, |
| | | SupplyCode = stockDetail.SupplyCode, |
| | | Unit = stockDetail.Unit |
| | | }; |
| | | } |
| | | |
| | | } |
| | | |
| | | List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>(); |
| | | |
| | | outboundOrderDetails.Add(outboundOrderDetail); |
| | | |
| | | decimal allocatedQuantity = actualOutboundQuantity; |
| | | List<Dt_OutboundOrderDetail> updateDetails = new(); |
| | | foreach (var item in outboundOrderDetails) |
| | | { |
| | | if (allocatedQuantity <= 0) break; |
| | | |
| | | decimal barcodeQuantity = allocatedQuantity; |
| | | |
| | | if (item.LockQuantity - item.OverOutQuantity >= allocatedQuantity) |
| | | { |
| | | item.OverOutQuantity += allocatedQuantity; |
| | | item.CurrentDeliveryQty += allocatedQuantity; |
| | | allocatedQuantity = 0; |
| | | } |
| | | else |
| | | { |
| | | barcodeQuantity = allocatedQuantity; |
| | | allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity); |
| | | item.OverOutQuantity = allocatedQuantity; |
| | | item.LockQuantity = allocatedQuantity; |
| | | item.CurrentDeliveryQty = allocatedQuantity; |
| | | } |
| | | |
| | | updateDetails.Add(item); |
| | | |
| | | List<Barcodes> barcodesList = new List<Barcodes>(); |
| | | Barcodes barcodes = new Barcodes |
| | | { |
| | | Barcode = isUnpacked ? newBarcode : stockDetail?.Barcode, |
| | | Qty = barcodeQuantity, |
| | | SupplyCode = stockDetail?.SupplyCode ?? "", |
| | | BatchNo = stockDetail?.BatchNo ?? "", |
| | | Unit = stockDetail?.Unit ?? "" |
| | | }; |
| | | if (!string.IsNullOrEmpty(item.ReturnJsonData)) |
| | | { |
| | | barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(item.ReturnJsonData) ?? new List<Barcodes>(); |
| | | } |
| | | barcodesList.Add(barcodes); |
| | | JsonSerializerSettings settings = new JsonSerializerSettings |
| | | { |
| | | ContractResolver = new CamelCasePropertyNamesContractResolver() |
| | | }; |
| | | item.ReturnJsonData = JsonConvert.SerializeObject(barcodesList, settings); |
| | | } |
| | | |
| | | // æ´æ°åºåºåæç»çå·²åºåºæ°é |
| | | _outboundOrderDetailRepository.UpdateData(updateDetails); |
| | | |
| | | // æ´æ°éå®è®°å½ç累计已åºåºæ°éï¼éè¦æ´æ°è¯¥æçè¯¥ç©æçææç¸å
³è®°å½ï¼ |
| | | //UpdateLockInfoAllocatedQuantity(stockInfo.Id, stockDetail.MaterielCode, stockDetail.BatchNo, actualOutboundQuantity); |
| | | |
| | | // æäº¤äºå¡ |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | // æå»ºè¿åä¿¡æ¯ |
| | | ScannedStockDetailDTO scannedDetail = new ScannedStockDetailDTO |
| | | { |
| | | StockDetailId = stockDetail.Id, |
| | | PalletCode = stockInfo.PalletCode, |
| | | MaterielCode = stockDetail.MaterielCode, |
| | | MaterielName = stockDetail.MaterielName, |
| | | BatchNo = stockDetail.BatchNo, |
| | | OriginalBarcode = request.Barcode, |
| | | BeforeQuantity = beforeQuantity, |
| | | AfterQuantity = isUnpacked ? actualOutboundQuantity : 0, |
| | | ChangeQuantity = -actualOutboundQuantity, |
| | | IsUnpacked = isUnpacked, |
| | | MaterialCodes = returnDTOs |
| | | }; |
| | | |
| | | response.Success = true; |
| | | response.Message = "åºåºå®æ"; |
| | | response.ScannedDetail = scannedDetail; |
| | | response.UpdatedDetails = updateDetails; |
| | | |
| | | if (!string.IsNullOrEmpty(newBarcode)) |
| | | { |
| | | // ç©ææ°æ¡ç åä¼ |
| | | _feedbackMesService.BarcodeFeedback(newBarcode); |
| | | } |
| | | |
| | | _feedbackMesService.OutboundFeedback(outboundOrder.OrderNo); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | response.Success = false; |
| | | response.Message = $"åºåºå¤ç失败ï¼{ex.Message}"; |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | |
| | | content = WebResponseContent.Instance.OK(data: response); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | content = WebResponseContent.Instance.Error("å¤çåºåºå®æå¤±è´¥ï¼" + ex.Message); |
| | | } |
| | | return content; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |