using LogLibrary.Log; using MailKit; using MailKit.Search; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Bcpg; using SixLabors.ImageSharp; using SqlSugar; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; using System.Net; using System.Reflection.Metadata; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.AllocateEnum; using WIDESEA_Common.CommonEnum; using WIDESEA_Common.OrderEnum; using WIDESEA_Common.StockEnum; using WIDESEA_Common.WareHouseEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.Helper; using WIDESEA_Core.Util; using WIDESEA_Core.Utilities; using WIDESEA_DTO.Allocate; using WIDESEA_DTO.Inbound; using WIDESEA_DTO.Mes; using WIDESEA_DTO.ReturnMES; using WIDESEA_IBasicService; using WIDESEA_IInboundService; using WIDESEA_IStockService; using WIDESEA_Model.Models; using WIDESEA_Model.Models.Basic; using WIDESEA_Model.Models.Check; namespace WIDESEA_InboundService { public class InboundService : IInboundService { LogFactory LogFactory = new LogFactory(); private readonly IUnitOfWorkManage _unitOfWorkManage; public IInboundOrderDetailService InboundOrderDetailService { get; } public IInboundOrderService InbounOrderService { get; } private readonly IRepository _inboundOrderRepository; private readonly IRepository _warehouseAreaRepository; private readonly IRepository _locationTypeRepository; private readonly IRepository _stockInfoRepository; private readonly IRepository _inboundOrderDetailRepository; private readonly IRepository _taskRepository; private IStockService _stockService; private readonly IRepository _allocateMaterialInfo; private readonly HttpClientHelper _httpClientHelper; private readonly IRepository _mesReturnRecord; private readonly ILocationInfoService _locationInfoService; private readonly IRepository _takeStockOrder; private readonly IRepository _stockInfoDetailRepository; private readonly IRepository _allocateOrderRepository; public InboundService(IUnitOfWorkManage unitOfWorkManage, IInboundOrderDetailService inboundOrderDetailService, IInboundOrderService inbounOrderService, IRepository inboundOrderRepository, IRepository warehouseAreaRepository, IRepository locationTypeRepository, IRepository stockInfoRepository, IRepository inboundOrderDetailRepository, IStockService stockService, IRepository taskRepository,IRepository allocateMaterialInfo, HttpClientHelper httpClientHelper, IRepository mesReturnRecord,ILocationInfoService locationInfoService,IRepository takeStockOrder,IRepository stockInfoDetailRepository, IRepository allocateOrderRepository) { _unitOfWorkManage = unitOfWorkManage; InboundOrderDetailService = inboundOrderDetailService; InbounOrderService = inbounOrderService; _inboundOrderRepository = inboundOrderRepository; _warehouseAreaRepository = warehouseAreaRepository; _locationTypeRepository = locationTypeRepository; _stockInfoRepository = stockInfoRepository; _inboundOrderDetailRepository = inboundOrderDetailRepository; _stockService = stockService; _taskRepository = taskRepository; _allocateMaterialInfo = allocateMaterialInfo; _httpClientHelper = httpClientHelper; _mesReturnRecord = mesReturnRecord; _locationInfoService = locationInfoService; _takeStockOrder = takeStockOrder; _stockInfoDetailRepository = stockInfoDetailRepository; _allocateOrderRepository = allocateOrderRepository; } public async Task GroupPallet(GroupPalletDto palletDto) { WebResponseContent content = new WebResponseContent(); try { (bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto); if (!result2.Item1) return content.Error(result2.Item2); var code = _warehouseAreaRepository.Db.Queryable().Where(x => x.Code == palletDto.WarehouseType).Select(x => x.Code).First(); if (string.IsNullOrEmpty(code)) { return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。"); } Dt_InboundOrder inboundOrder = new Dt_InboundOrder(); var details = _inboundOrderDetailRepository.QueryData(x => (x.OutBoxbarcodes == palletDto.Barcode|| x.Barcode == palletDto.Barcode) && x.OrderDetailStatus == (int)InOrderStatusEnum.未开始); if (details.Count() <= 0) { var inbounddetail = _inboundOrderDetailRepository.QueryFirst(x => x.Barcode == palletDto.Barcode || x.OutBoxbarcodes == palletDto.Barcode); if (inbounddetail == null) { return content.Error($"条码{palletDto.Barcode}不存在"); } var inbound = _inboundOrderRepository.Db.Queryable().Where(x => x.Id == inbounddetail.OrderId).First(); if (inbound == null) { return content.Error("单据不能为空"); } var detail = _inboundOrderDetailRepository.Db.Queryable().LeftJoin((d, o) => d.OrderId == o.Id).Where((d, o) => d.OrderId == inbound.Id && d.ReceiptQuantity != 0 && d.OverInQuantity == 0).Select((d, o) => new { orderNo = o.InboundOrderNo, d.Barcode, d.MaterielCode, d.BatchNo, d.ReceiptQuantity, d.Unit, d.SupplyCode, d.WarehouseCode }).ToList(); var palletId = _stockInfoDetailRepository.QueryFirst(x => x.Barcode == palletDto.Barcode); if (palletId == null) { return content.Error($"条码{palletDto.Barcode}已组盘"); } var pallet = _stockInfoRepository.QueryFirst(x => x.Id == palletId.StockId); return content.Error($"条码{palletDto.Barcode}已经组到{pallet.PalletCode}", detail); } inboundOrder = _inboundOrderRepository.Db.Queryable().Includes(x=>x.Details).Where(x => x.Id == details.First().OrderId).First(); if (inboundOrder == null) { return content.Error("未找到该条码主单信息"); } if(inboundOrder.OrderStatus == (int)InOrderStatusEnum.手动关闭) { return content.Error("该单据的状态不能组盘"); } var warehouse =_warehouseAreaRepository.QueryFirst(x => x.Code == palletDto.WarehouseType); if(inboundOrder.BusinessType=="11" && inboundOrder.FactoryArea != warehouse.FactoryArea) { return content.Error($"当前厂区不一致"); } if(inboundOrder.BusinessType != "11") { var warehouseType = _inboundOrderDetailRepository.Db.Queryable().Where(x => (x.Barcode == palletDto.Barcode || x.OutBoxbarcodes == palletDto.Barcode)&& x.OrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()).Select(x => x.WarehouseCode).First(); if (string.IsNullOrEmpty(warehouseType)) { return content.Error($"未查询到条码[{palletDto.Barcode}]对应的仓库信息,不允许组盘"); } if (!warehouseType.Equals(palletDto.WarehouseType)) { return content.Error($"该条码所属仓库为{warehouseType}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘"); } } Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync(); List materielCodes = details.GroupBy(x => x.Barcode).Select(x => x.Key).ToList(); (bool, string, object?) result = CheckMaterielGroupParam(palletDto, materielCodes, inboundOrder, stockInfo); if (!result.Item1) return content = WebResponseContent.Instance.Error(result.Item2); if (stockInfo == null) { stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = Convert.ToInt32(palletDto.locationType) }; stockInfo.Details = new List(); } //else //{ // var allowStatus = new[] // { // (int)StockStatusEmun.组盘暂存, // (int)StockStatusEmun.智仓入智仓组盘暂存, // (int)StockStatusEmun.手动组盘暂存 // }; // if (!allowStatus.Contains(stockInfo.StockStatus)) // { // return content.Error($"该托盘{stockInfo.PalletCode}状态不允许组盘"); // } //} if (inboundOrder.BusinessType != MESDocumentType.PurchaseInbound.ToString() && stockInfo != null && stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType) { return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘"); } var isWarehouse = _inboundOrderDetailRepository.QueryFirst(x => x.OrderId == inboundOrder.Id && !string.IsNullOrEmpty(x.WarehouseCode)); if (isWarehouse != null && inboundOrder.BusinessType == "11" && isWarehouse.WarehouseCode != palletDto.WarehouseType) { return content.Error($"一个采购单据里面不允许组盘两个仓库,请重新选择仓库,上一个组盘仓库为{isWarehouse.WarehouseCode}"); } if (inboundOrder.BusinessType == "11" && inboundOrder.IsTestMaterials == 1 && palletDto.WarehouseType != "1076" && palletDto.WarehouseType != "5057") { return content.Error($"该单据为试产物料,需要入库到试产仓,请重新根据厂区选择试产仓库进行组盘入库"); } if (inboundOrder.IsTestMaterials == 0 && (palletDto.WarehouseType == "1076" || palletDto.WarehouseType == "5057")) { return content.Error($"该单据为非试产物料,不能入到试产仓,请重新根据仓库进行组盘入库"); } if (!_locationInfoService.QueryLocationCount(Convert.ToInt32(palletDto.locationType))) { return content.Error($"该库区{palletDto.locationType}不存在空闲库位"); } var nullpallet =_stockInfoRepository.QueryFirst(x => x.PalletType == -1 && x.PalletCode == palletDto.PalletCode); if (nullpallet != null) { return content.Error($"该托盘{palletDto.PalletCode}已经进行空托组盘,不能在进行组盘"); } var outbundPallet = _stockInfoRepository.QueryFirst(x => x.StockStatus == (int)StockStatusEmun.出库完成 && x.PalletCode == palletDto.PalletCode); if (outbundPallet != null) { return content.Error($"该托盘{palletDto.PalletCode}未进行取空箱,不能进行组盘"); } foreach (var item in details) { var datevaliDate = _inboundOrderRepository.Db.Queryable().Where(x => x.MaterialCode.Contains(item.MaterielCode.Substring(0, 6))).First(); if (datevaliDate == null) { return content.Error($"该物料{item.MaterielCode}未找到MES推送的有效期数据,请先添加该物料的有效期再组盘入库"); } stockInfo.Details.Add(new Dt_StockInfoDetail { StockId = stockInfo == null ? 0 : stockInfo.Id, Barcode = item.Barcode, MaterielCode = item.MaterielCode, MaterielName = item.MaterielName, BatchNo = item.BatchNo, Unit = item.Unit, InboundOrderRowNo = item.lineNo, SupplyCode = item.SupplyCode, WarehouseCode = palletDto.WarehouseType, StockQuantity = item.OrderQuantity, BarcodeQty = item.BarcodeQty, BarcodeUnit = item.BarcodeUnit, FactoryArea = inboundOrder.FactoryArea, Status = 0, OrderNo = inboundOrder.InboundOrderNo, BusinessType = inboundOrder.BusinessType, ValidDate = inboundOrder.BusinessType == BusinessTypeEnum.外部仓库调智仓.ToString() ? item.ValidDate : datevaliDate == null ? null : Convert.ToDateTime(DateTime.Now).AddDays(Convert.ToDouble(datevaliDate.ValidityDays)), }); item.ReceiptQuantity = item.BarcodeQty; item.OrderDetailStatus = (int)OrderDetailStatusEnum.GroupAndInbound; item.WarehouseCode = palletDto.WarehouseType; item.ReturnToMESStatus = 0; } if (stockInfo.Id == 0) { stockInfo.PalletCode = palletDto.PalletCode; stockInfo.StockStatus = (int)StockStatusEmun.组盘暂存; } stockInfo.PalletType = (int)PalletTypeEnum.None; List updateDetailIds = details.Select(x => x.Id).ToList(); if (inboundOrder.OrderStatus == (int)InOrderStatusEnum.未开始) { inboundOrder.OrderStatus = (int)InOrderStatusEnum.入库中; } inboundOrder.Operator = App.User.UserName; content = MaterielGroupUpdateData(inboundOrder, details, stockInfo).Result; if (content.Status) { Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync(); return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id)); } else { content = WebResponseContent.Instance.Error(content.Message); } } catch (Exception ex) { LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}"); return content.Error(ex.Message); } return content; } public async Task AllcatedGroupPallet(GroupPalletDto palletDto) { WebResponseContent content = new WebResponseContent(); try { (bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto); if (!result2.Item1) return content.Error(result2.Item2); var code = _warehouseAreaRepository.Db.Queryable().Where(x => x.Code == palletDto.WarehouseType).Select(x => x.Code).First(); if (string.IsNullOrEmpty(code)) { return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。"); } Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync(); if (_taskRepository.QueryFirst(x => x.PalletCode == palletDto.PalletCode) != null) { return content.Error($"该托盘已生成任务"); } if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存) { return content.Error("已上架的托盘不能再次组盘"); } var nullpallet = _stockInfoRepository.QueryFirst(x => x.PalletType == -1 && x.PalletCode == palletDto.PalletCode); if (nullpallet != null) { return content.Error($"该托盘{palletDto.PalletCode}已经进行空托组盘,不能在进行组盘"); } var outbundPallet = _stockInfoRepository.QueryFirst(x => x.StockStatus == (int)StockStatusEmun.出库完成 && x.PalletCode == palletDto.PalletCode); if (outbundPallet != null) { return content.Error($"该托盘{palletDto.PalletCode}未进行取空箱,不能进行组盘"); } if (_stockService.StockInfoDetailService.ExistBarcodes(palletDto.Barcode)) { return content.Error($"{palletDto.Barcode} 条码在库存中已存在"); } if (stockInfo == null) { stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = Convert.ToInt32(palletDto.locationType) }; stockInfo.Details = new List(); } if (stockInfo != null && stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType) { return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘"); } Dt_AllocateMaterialInfo allocateMaterialInfo = _allocateMaterialInfo.QueryFirst(x => x.Barcode == palletDto.Barcode); if(allocateMaterialInfo == null) { return content.Error($"未找到该条码{palletDto.Barcode}需调入智仓的信息"); } if(allocateMaterialInfo.WarehouseCode != palletDto.WarehouseType) { return content.Error($"该条码调入仓库为{allocateMaterialInfo.WarehouseCode},与选择的{palletDto.WarehouseType}仓库不一致"); } stockInfo.Details.Add(new Dt_StockInfoDetail { StockId = stockInfo == null ? 0 : stockInfo.Id, Barcode = allocateMaterialInfo.Barcode, MaterielCode = allocateMaterialInfo.MaterialCode, BatchNo = allocateMaterialInfo.BatchNo, Unit = allocateMaterialInfo.Unit, SupplyCode = allocateMaterialInfo.SupplyCode, WarehouseCode = palletDto.WarehouseType, StockQuantity = allocateMaterialInfo.Quantity, BarcodeQty = allocateMaterialInfo.Quantity, BarcodeUnit = allocateMaterialInfo.Unit, FactoryArea = allocateMaterialInfo.FactoryArea, Status = 0, OrderNo = allocateMaterialInfo.OrderNo, BusinessType = "1", }); if (stockInfo.Id == 0) { stockInfo.PalletCode = palletDto.PalletCode; stockInfo.StockStatus = (int)StockStatusEmun.智仓入智仓组盘暂存; } stockInfo.PalletType = (int)PalletTypeEnum.None; _unitOfWorkManage.BeginTran(); _stockService.StockInfoService.AddMaterielGroup(stockInfo); _unitOfWorkManage.CommitTran(); Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync(); return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id)); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}"); return content.Error(ex.Message); } } /// /// 验证组盘数据 /// /// 物料组盘DTO /// 扫码序列号 /// 物料信息 /// 物料编号 /// 入库单据 /// 组盘信息 /// public (bool, string, object?) CheckMaterielGroupParam(GroupPalletDto materielGroupDTO, List barcodeCodes, Dt_InboundOrder inboundOrder, Dt_StockInfo stockInfo) { (bool, string, object?) result = ModelValidate.ValidateModelData(materielGroupDTO); if (!result.Item1) return result; if (_taskRepository.QueryFirst(x => x.PalletCode == materielGroupDTO.PalletCode) != null) { return (false, "该托盘号已有任务", materielGroupDTO); } if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存) { return (false, "已上架的托盘不能再次组盘", materielGroupDTO); } if (_stockService.StockInfoDetailService.ExistBarcodes(barcodeCodes)) { return (false, $"{barcodeCodes[0]} 条码在库存中已存在", materielGroupDTO); } if (inboundOrder == null) { return (false, "单据不存在", materielGroupDTO); } if (inboundOrder.Details == null || inboundOrder.Details.Count == 0) { return (false, "无单据明细信息", materielGroupDTO); } if (inboundOrder.OrderStatus != (int)InOrderStatusEnum.未开始 && inboundOrder.OrderStatus != (int)InOrderStatusEnum.入库中) { return (false, "该单据不可再组盘", materielGroupDTO); } List inboundOrderDetails = inboundOrder.Details.Where(x => barcodeCodes.Contains(x.Barcode)).ToList(); if (inboundOrderDetails.GroupBy(x => x.Barcode).Count() != barcodeCodes.Count) { return (false, "有物料不在单据内", materielGroupDTO); } return (true, "成功", materielGroupDTO); } public async Task MaterielGroupUpdateData(Dt_InboundOrder inboundOrder, List inboundOrderDetails, Dt_StockInfo stockInfo) { try { _unitOfWorkManage.BeginTran(); //await _inboundOrderRepository.Db.UpdateNav(inboundOrder).Include(x=>x.Details).ExecuteCommandAsync(); _inboundOrderRepository.UpdateData(inboundOrder); _inboundOrderDetailRepository.UpdateData(inboundOrderDetails); _stockService.StockInfoService.AddMaterielGroup(stockInfo); _unitOfWorkManage.CommitTran(); return WebResponseContent.Instance.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent BatchInOrderFeedbackToMes(int id) { WebResponseContent content = new WebResponseContent(); try { Dt_InboundOrder inboundOrder = null; var allocateOrder = _allocateOrderRepository.Db.Queryable().Where(x => x.Id == id).First(); if (allocateOrder != null) { inboundOrder = _inboundOrderRepository.Db.Queryable().Where(x => x.InboundOrderNo == allocateOrder.OrderNo).First(); if (inboundOrder.IsBatch == 0 && inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { return content = WebResponseContent.Instance.OK($"该单据属于不分批自动回传,不可手动分批回传"); } }else { inboundOrder = _inboundOrderRepository.Db.Queryable() .Where(x => x.Id == id) .First(); if (inboundOrder.IsBatch == 0 && inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { return content = WebResponseContent.Instance.OK($"该单据属于不分批自动回传,不可手动分批回传"); } } List returnRecords = _mesReturnRecord.QueryData(x => x.OrderNo == inboundOrder.InboundOrderNo && x.OrderId == inboundOrder.Id && x.ReturnStatus == 2); foreach (var item in returnRecords) { HttpResponseResult httpResponse = _httpClientHelper.Post(item.ApiUrl, item.RequestData); item.ReturnCount += 1; bool success = httpResponse.IsSuccess && httpResponse.Data.Code == "200"; item.ReturnStatus = success ? 1 : 2; item.HttpStatusCode = httpResponse.StatusCode.ObjToInt(); item.LastReturnTime = DateTime.Now; item.ResponseData = httpResponse.Content; item.SuccessTime = httpResponse.IsSuccess ? DateTime.Now : null; //List details=new List(); //foreach (var y in item.DetailsId.Split(',')) //{ // details.Add( _inboundOrderDetailRepository.QueryFirst(x => x.Id == Convert.ToInt32(y))); //} } _mesReturnRecord.UpdateData(returnRecords); //重新回调完成的单据,更新库存状态 foreach (var returnRecord in returnRecords) { if (returnRecord.ReturnStatus == 1) { _stockInfoRepository.Db.Updateable().SetColumns(it => new Dt_StockInfoDetail { Status = StockStatusEmun.入库完成.ObjToInt() }).Where(it => it.OrderNo == returnRecord.OrderNo && returnRecord.RequestData.Contains(it.Barcode)).ExecuteCommand(); } } var inboundOrderDetail = _inboundOrderRepository.Db.Queryable() .Where(x => x.OrderId == inboundOrder.Id && x.OrderDetailStatus == (int)OrderDetailStatusEnum.Over && x.ReturnToMESStatus == 0) .ToList(); var stocks = _stockInfoRepository.Db.Queryable().Where(x => x.StockStatus == (int)StockStatusEmun.入库完成) .Where(it => SqlFunc.Subqueryable().Where(s => s.StockId == it.Id && s.OrderNo == inboundOrder.InboundOrderNo && s.Status == StockStatusEmun.入库确认.ObjToInt()).Any()) .ToList(); var stockIds = stocks.Select(s => s.Id).ToList(); var allDetailsData = _stockInfoRepository.Db.Queryable() .Where(x => stockIds.Contains(x.StockId)) .ToList(); var matchedData = inboundOrderDetail .Join(allDetailsData, inbound => inbound.Barcode, stockdetail => stockdetail.Barcode, (inbound, stockdetail) => inbound.Barcode) .ToList(); var inbounddetailID = inboundOrderDetail .Join(allDetailsData, inbound => inbound.Barcode, stockdetail => stockdetail.Barcode, (inbound, stockdetail) => inbound.Id) .ToList(); var inbounddetailBarcode = inboundOrderDetail .Join(allDetailsData, inbound => inbound.Barcode, stockdetail => stockdetail.Barcode, (inbound, stockdetail) => stockdetail.Barcode) .ToList(); var detail = allDetailsData.Where(x => matchedData.Contains(x.Barcode)).ToList(); if (inboundOrder.OrderType == (int)InOrderTypeEnum.AllocatInbound)//调拨入库 { var allocate = _inboundOrderRepository.Db.Queryable().Where(x => x.OrderNo == inboundOrder.InboundOrderNo).First(); var allocatefeedmodel = new AllocateDto { ReqCode = Guid.NewGuid().ToString(), ReqTime = DateTime.Now.ToString(), BusinessType = "3", FactoryArea = inboundOrder.FactoryArea, OperationType = 1, Operator = inboundOrder.Operator, OrderNo = inboundOrder.UpperOrderNo, fromWarehouse = allocate?.FromWarehouse ?? "", toWarehouse = allocate?.ToWarehouse ?? "", Details = GetAllocateDtoDetails(detail) }; if (allocatefeedmodel.Details.Count <= 0) { if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 1)) { if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt()) { inboundOrder.ReturnToMESStatus = 1; } else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { inboundOrder.ReturnToMESStatus = 3; } else { inboundOrder.ReturnToMESStatus = 0; } } else if (returnRecords.Count(x => x.ReturnStatus == 2) > 0) { inboundOrder.ReturnToMESStatus = 4; } else if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 2)) { inboundOrder.ReturnToMESStatus = 2; } _inboundOrderRepository.UpdateData(inboundOrder); return WebResponseContent.Instance.OK($"该单据没有需要回传明细,回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条"); } var response = responseModel(inboundOrder, 3, null, allocatefeedmodel); if (response != null && response.IsSuccess) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 }) .Where(it => it.OrderId == inboundOrder.Id && inbounddetailID.Contains(it.Id)).ExecuteCommand(); if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 3 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } _stockInfoRepository.Db.Updateable().SetColumns(it => new Dt_StockInfoDetail { Status = StockStatusEmun.入库完成.ObjToInt() }).Where(it => it.OrderNo == inboundOrder.InboundOrderNo && inbounddetailBarcode.Contains(it.Barcode)).ExecuteCommand(); } else { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 }) .Where(it => inbounddetailID.Contains(it.Id)).ExecuteCommand(); if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 4 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } return content.Error("回传MES失败"); } } else { var feedmodel = new FeedbackInboundRequestModel { reqCode = Guid.NewGuid().ToString(), reqTime = DateTime.Now.ToString(), business_type = inboundOrder.BusinessType, factoryArea = inboundOrder.FactoryArea, operationType = 1, Operator = inboundOrder.Operator, orderNo = inboundOrder.UpperOrderNo, status = inboundOrder.OrderStatus, details = FeedbackInboundDetailsModelDto(detail) }; if (feedmodel.details.Count <= 0) { if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 1)) { if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt()) { inboundOrder.ReturnToMESStatus = 1; } else if(inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { inboundOrder.ReturnToMESStatus = 3; } else { inboundOrder.ReturnToMESStatus = 0; } } else if (returnRecords.Count(x => x.ReturnStatus == 2) > 0) { inboundOrder.ReturnToMESStatus = 4; } else if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 2)) { inboundOrder.ReturnToMESStatus = 2; } _inboundOrderRepository.UpdateData(inboundOrder); return WebResponseContent.Instance.OK($"该单据没有需要回传明细,回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条"); } var response = responseModel(inboundOrder, 3, feedmodel); if (response != null && response.IsSuccess) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 }) .Where(it => inbounddetailID.Contains(it.Id)).ExecuteCommand(); if(inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else if(inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 3}) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } _stockInfoRepository.Db.Updateable().SetColumns(it => new Dt_StockInfoDetail { Status = StockStatusEmun.入库完成.ObjToInt() }).Where(it => it.OrderNo == inboundOrder.InboundOrderNo && inbounddetailBarcode.Contains(it.Barcode)).ExecuteCommand(); } else { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 }) .Where(it => inbounddetailID.Contains(it.Id)).ExecuteCommand(); if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt()) { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 4 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } else { _inboundOrderRepository.Db.Updateable().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 }) .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); } return content.Error("回传MES失败"); } } return content.OK("回传MES成功"); } catch (Exception ex) { return content.Error(ex.Message); } } public List GetAllocateDtoDetails(List stockInfoDetails) { var groupedData = stockInfoDetails.GroupBy(item => new { item.MaterielCode, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode }) .Select(group => new AllocateDtoDetail { MaterialCode = group.Key.MaterielCode, LineNo = group.Key.InboundOrderRowNo, WarehouseCode = group.Key.WarehouseCode, Qty = group.Sum(x => x.BarcodeQty), Unit = group.Key.BarcodeUnit, Barcodes = group.Select(row => new BarcodeInfo { Barcode = row.Barcode, Qty = row.BarcodeQty, BatchNo = row.BatchNo, SupplyCode = row.SupplyCode, Unit = row.BarcodeUnit }).ToList() }).ToList(); return groupedData; } public List FeedbackInboundDetailsModelDto(List stockInfoDetails) { var groupedData = stockInfoDetails.GroupBy(item => new { item.MaterielCode, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode }) .Select(group => new FeedbackInboundDetailsModel { materialCode = group.Key.MaterielCode, lineNo = group.Key.InboundOrderRowNo, warehouseCode = group.Key.WarehouseCode, qty = group.Sum(x => x.BarcodeQty), unit = group.Key.BarcodeUnit, barcodes = group.Select(row => new FeedbackBarcodesModel { barcode = row.Barcode, qty = row.BarcodeQty }).ToList() }).ToList(); return groupedData; } public HttpResponseResult responseModel(Dt_InboundOrder order, int InterfaceType, FeedbackInboundRequestModel model = null, AllocateDto allocateDto = null) { HttpResponseResult httpResponseResult = new HttpResponseResult(); string reqCode = Guid.NewGuid().ToString(); string reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string requestData = string.Empty; string apiUrl = string.Empty; if (model != null) { apiUrl = AppSettings.GetValue("AldMaterialWarehousing"); httpResponseResult = _httpClientHelper.Post(apiUrl, model.Serialize()); requestData = model.Serialize(); } else { apiUrl = AppSettings.GetValue("AldAllocationOperation"); httpResponseResult = _httpClientHelper.Post(apiUrl, allocateDto.Serialize()); requestData = allocateDto.Serialize(); } 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 = InterfaceType, OrderId = order.Id, OrderNo = order.InboundOrderNo, 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.Db.Insertable(mesReturnRecord).ExecuteCommand(); return httpResponseResult; } public async Task StockTakeGroupPallet(GroupPalletDto palletDto) { WebResponseContent content = new WebResponseContent(); try { (bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto); if (!result2.Item1) return content.Error(result2.Item2); // 验证仓库编号是否存在 var code = _warehouseAreaRepository.Db.Queryable() .Where(x => x.Code == palletDto.WarehouseType) .Select(x => x.Code) .First(); if (string.IsNullOrEmpty(code)) { return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。"); } // 查询当前托盘的库存信息 Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable() .Includes(x => x.Details) .Where(x => x.PalletCode == palletDto.PalletCode) .FirstAsync(); // 验证托盘是否已生成任务 if (_taskRepository.QueryFirst(x => x.PalletCode == palletDto.PalletCode) != null) { return content.Error($"该托盘已生成任务"); } // 验证托盘是否已上架(已上架不能组盘) if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存) { return content.Error("已上架的托盘不能再次组盘"); } var nullpallet = _stockInfoRepository.QueryFirst(x => x.PalletType == -1 && x.PalletCode == palletDto.PalletCode); if (nullpallet != null) { return content.Error($"该托盘{palletDto.PalletCode}已经进行空托组盘,不能在进行组盘"); } var outbundPallet = _stockInfoRepository.QueryFirst(x => x.StockStatus == (int)StockStatusEmun.出库完成 && x.PalletCode == palletDto.PalletCode); if (outbundPallet != null) { return content.Error($"该托盘{palletDto.PalletCode}未进行取空箱,不能进行组盘"); } Dt_StockInfoDetail stockInfoDetail = _stockService.StockInfoDetailService.Db.Queryable() .Where(x => x.Barcode == palletDto.Barcode && x.StockId == 0) .First(); if (stockInfoDetail == null) { return content.Error($"{palletDto.Barcode} 条码已关联其他托盘,无法组盘"); } Dt_TakeStockOrder takeStockOrder = _takeStockOrder.Db.Queryable() .Where(x => x.OrderNo == stockInfoDetail.OrderNo) .First(); if (takeStockOrder == null) { return content.Error($"{palletDto.Barcode} 不属于盘点单据中的条码,不允许盘亏组盘"); } if (stockInfo == null) { stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = Convert.ToInt32(palletDto.locationType), PalletCode = palletDto.PalletCode, StockStatus = (int)StockStatusEmun.组盘暂存, Details = new List() }; } if (stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType) { return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘"); } _unitOfWorkManage.BeginTran(); try { if (stockInfo.Id == 0) { int newStockId = await _stockInfoRepository.Db.Insertable(stockInfo).ExecuteReturnIdentityAsync(); stockInfo.Id = newStockId; } stockInfoDetail.StockId = stockInfo.Id; await _stockService.StockInfoDetailService.Db.Updateable(stockInfoDetail) .Where(x => x.Id == stockInfoDetail.Id) .ExecuteCommandAsync(); if (stockInfo.Id != 0 && stockInfo.Details != null && !stockInfo.Details.Contains(stockInfoDetail)) { stockInfo.Details.Add(stockInfoDetail); await _stockInfoRepository.Db.Updateable(stockInfo) .IgnoreColumns(x => x.Details) .ExecuteCommandAsync(); } // 提交事务 _unitOfWorkManage.CommitTran(); } catch (Exception) { // 事务回滚 _unitOfWorkManage.RollbackTran(); throw; // 抛给外层catch处理日志 } // 查询最新的库存信息(包含关联的明细) Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable() .Includes(x => x.Details) .Where(x => x.PalletCode == palletDto.PalletCode) .FirstAsync(); return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id)); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}"); return content.Error(ex.Message); } } public async Task ReCheckGroupPallet(GroupPalletDto palletDto) { WebResponseContent content = new WebResponseContent(); try { (bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto); if (!result2.Item1) return content.Error(result2.Item2); var code = _warehouseAreaRepository.Db.Queryable().Where(x => x.Code == palletDto.WarehouseType).Select(x => x.Code).First(); if (string.IsNullOrEmpty(code)) { return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。"); } Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync(); if (_taskRepository.QueryFirst(x => x.PalletCode == palletDto.PalletCode) != null) { return content.Error($"该托盘已生成任务"); } if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存) { return content.Error("已上架的托盘不能再次组盘"); } if (stockInfo == null) { stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = Convert.ToInt32(palletDto.locationType) }; stockInfo.Details = new List(); } if (stockInfo != null && stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType) { return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘"); } var nullpallet = _stockInfoRepository.QueryFirst(x => x.PalletType == -1 && x.PalletCode == palletDto.PalletCode); if (nullpallet != null) { return content.Error($"该托盘{palletDto.PalletCode}已经进行空托组盘,不能在进行组盘"); } var outbundPallet = _stockInfoRepository.QueryFirst(x => x.StockStatus == (int)StockStatusEmun.出库完成 && x.PalletCode == palletDto.PalletCode); if (outbundPallet != null) { return content.Error($"该托盘{palletDto.PalletCode}未进行取空箱,不能进行组盘"); } Dt_StockInfoDetail stockInfoDetail = _stockInfoRepository.Db.Queryable().Where(x => x.Barcode == palletDto.Barcode && x.Status == StockStatusEmun.重检中.ObjToInt()).First(); if(stockInfoDetail == null) { return content.Error("未找到库存中重检冻结的条码"); } Dt_ReCheckOrder reCheckOrder = _stockInfoRepository.Db.Queryable().Where(x => x.MaterielCode == stockInfoDetail.MaterielCode && x.BatchNo == stockInfoDetail.BatchNo && x.OrderNo == stockInfoDetail.OrderNo && (x.Result == 1 || x.Result == 2 )).First(); if(reCheckOrder == null) { return content.Error($"该重检条码的批次在重检单中未拿到重检结果,请检查重检单中物料{stockInfoDetail.MaterielCode}和{stockInfoDetail.BatchNo}物料批次状态"); } int newStatus = reCheckOrder.Result == 1 ? StockStatusEmun.入库完成.ObjToInt(): StockStatusEmun.手动冻结.ObjToInt(); stockInfo.Details.Add(new Dt_StockInfoDetail { StockId = stockInfo == null ? 0 : stockInfo.Id, Barcode = stockInfoDetail.Barcode, MaterielCode = stockInfoDetail.MaterielCode, MaterielName = stockInfoDetail.MaterielName, BatchNo = stockInfoDetail.BatchNo, Unit = stockInfoDetail.Unit, SupplyCode = stockInfoDetail.SupplyCode, WarehouseCode = stockInfoDetail.WarehouseCode, StockQuantity = stockInfoDetail.StockQuantity, BarcodeQty = stockInfoDetail.BarcodeQty, BarcodeUnit = stockInfoDetail.BarcodeUnit, FactoryArea = stockInfoDetail.FactoryArea, Status = newStatus, OrderNo = stockInfoDetail.OrderNo, BusinessType = "30", ValidDate = stockInfoDetail.ValidDate }); _stockInfoRepository.Db.Deleteable().Where(x => x.Barcode == stockInfoDetail.Barcode).ExecuteCommand(); if (stockInfo.Id == 0) { stockInfo.PalletCode = palletDto.PalletCode; stockInfo.StockStatus = (int)StockStatusEmun.送检库存完成; } stockInfo.PalletType = (int)PalletTypeEnum.None; _unitOfWorkManage.BeginTran(); _stockService.StockInfoService.AddMaterielGroup(stockInfo); _unitOfWorkManage.CommitTran(); Dt_StockInfo oldStockInfo = _stockInfoRepository.Db.Queryable().Where(x => x.Id == stockInfoDetail.StockId).Includes(x=>x.Details).First(); if (oldStockInfo.Details.Count <= 0) { oldStockInfo.PalletType = (int)PalletTypeEnum.Empty; } _stockInfoRepository.UpdateData(oldStockInfo); Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync(); return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id)); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}"); return content.Error(ex.Message); } } } }