| | |
| | | using MailKit.Search; |
| | | using Microsoft.AspNetCore.Http; |
| | | using Microsoft.Extensions.Logging; |
| | | using Newtonsoft.Json; |
| | | using OfficeOpenXml; |
| | | using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; |
| | | using SqlSugar; |
| | | using System; |
| | |
| | | using WIDESEA_Model.Models.Check; |
| | | using WIDESEA_Model.Models.Outbound; |
| | | |
| | | |
| | | namespace WIDESEA_TaskInfoService |
| | | { |
| | | public partial class TaskService |
| | |
| | | /// </summary> |
| | | /// <param name="inTask"></param> |
| | | /// <returns></returns> |
| | | public async Task<WebResponseContent> PalletOutboundTask(int num, int locationType) |
| | | // æ¹æ³å¢å äº string? SupplierCode å¯éåæ° |
| | | public async Task<WebResponseContent> PalletOutboundTask(int num, int locationType, string? supplierCode = null) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | try |
| | | { |
| | | Dictionary<string, SqlSugar.OrderByType> orderByDict = new Dictionary<string, SqlSugar.OrderByType>() |
| | | { |
| | | { nameof(Dt_LocationInfo.Layer), SqlSugar.OrderByType.Asc }, |
| | | { nameof(Dt_LocationInfo.Row), SqlSugar.OrderByType.Asc }, |
| | | { nameof(Dt_LocationInfo.Column), SqlSugar.OrderByType.Asc }, |
| | | { nameof(Dt_LocationInfo.Depth), SqlSugar.OrderByType.Desc }, |
| | | }; |
| | | { |
| | | { nameof(Dt_LocationInfo.Layer), SqlSugar.OrderByType.Asc }, |
| | | { nameof(Dt_LocationInfo.Row), SqlSugar.OrderByType.Asc }, |
| | | { nameof(Dt_LocationInfo.Column), SqlSugar.OrderByType.Asc }, |
| | | { nameof(Dt_LocationInfo.Depth), SqlSugar.OrderByType.Desc }, |
| | | }; |
| | | |
| | | var query = _stockRepository.Db.Queryable<Dt_StockInfo>() |
| | | .Where(x => x.PalletType == PalletTypeEnum.Empty.ObjToInt() |
| | |
| | | .WhereIF(locationType != 0, x => x.LocationType == locationType) |
| | | .LeftJoin<Dt_LocationInfo>((s, l) => s.LocationCode == l.LocationCode); |
| | | |
| | | if (query.Count() == 0) |
| | | if (!await query.AnyAsync()) |
| | | { |
| | | return WebResponseContent.Instance.Error("æªæ¾å°ç©ºæçåºå"); |
| | | } |
| | |
| | | } |
| | | else |
| | | { |
| | | query = query.OrderBy(sortSql); |
| | | query.OrderBy(sortSql); |
| | | } |
| | | } |
| | | |
| | | var stockInfos = await query.Take(num).ToListAsync(); |
| | | |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | Dt_PlasticContainerLedger? todayLedger = null; |
| | | var today = DateTime.Now.Date; |
| | | var tomorrow = today.AddDays(1); |
| | | |
| | | if (!string.IsNullOrWhiteSpace(supplierCode)) |
| | | { |
| | | todayLedger = await _stockRepository.Db.Queryable<Dt_PlasticContainerLedger>() |
| | | .Where(x => x.SupplyCode == supplierCode) |
| | | .Where(x => x.CreateDate >= today && x.CreateDate < tomorrow) |
| | | .FirstAsync(); |
| | | } |
| | | |
| | | string allTaskNums = string.Empty; |
| | | |
| | | foreach (var stockInfo in stockInfos) |
| | | { |
| | | Dt_LocationInfo locationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode); |
| | | Dt_LocationInfo locationInfo = await _locationInfoService.Repository.QueryFirstAsync(x => x.LocationCode == stockInfo.LocationCode); |
| | | if (locationInfo == null) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error("æªæ¾å°ç©ºæçåºå对åºçè´§ä½ä¿¡æ¯"); |
| | | } |
| | | |
| | |
| | | TaskType = TaskTypeEnum.OutEmpty.ObjToInt(), |
| | | WarehouseId = stockInfo.WarehouseId, |
| | | PalletType = stockInfo.PalletType |
| | | |
| | | }; |
| | | int beforeStatus = locationInfo.LocationStatus; |
| | | _unitOfWorkManage.BeginTran(); |
| | | stockInfo.StockStatus = StockStatusEmun.åºåºéå®.ObjToInt(); |
| | | locationInfo.LocationStatus = LocationStatusEnum.Lock.ObjToInt(); |
| | | |
| | | int taskId = BaseDal.AddData(task); |
| | | int taskId = await BaseDal.AddDataAsync(task); |
| | | task.TaskId = taskId; |
| | | allTaskNums += task.TaskNum + ","; |
| | | |
| | | |
| | | stockInfo.StockStatus = StockStatusEmun.åºåºéå®.ObjToInt(); |
| | | _stockService.StockInfoService.UpdateData(stockInfo); |
| | | |
| | | int beforeStatus = locationInfo.LocationStatus; |
| | | locationInfo.LocationStatus = LocationStatusEnum.Lock.ObjToInt(); |
| | | _locationInfoService.UpdateData(locationInfo); |
| | | |
| | | _recordService.LocationStatusChangeRecordSetvice.AddLocationStatusChangeRecord(locationInfo, beforeStatus, StockChangeType.Outbound.ObjToInt(), "", task.TaskNum); |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | _recordService.LocationStatusChangeRecordSetvice.AddLocationStatusChangeRecord( |
| | | locationInfo, beforeStatus, StockChangeType.Outbound.ObjToInt(), "", task.TaskNum); |
| | | } |
| | | |
| | | if (!string.IsNullOrWhiteSpace(supplierCode)) |
| | | { |
| | | var ledgerList = new List<Dt_PlasticContainerLedger>(); |
| | | |
| | | foreach (var stock in stockInfos) |
| | | { |
| | | ledgerList.Add(new Dt_PlasticContainerLedger |
| | | { |
| | | SupplyCode = supplierCode, |
| | | PalletCode = stock.PalletCode, |
| | | CreateDate = DateTime.Now, |
| | | Creater = App.User?.ToString() |
| | | }); |
| | | } |
| | | _plasticContainerLedger.AddData(ledgerList); |
| | | } |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | return content.OK("空æåºåºæå!"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 宿¶æç´¢ä¾åºåç¼ç ï¼æ¯æè¾å
¥ r èªå¨å¹é
ï¼ä¸ææ¡ç¨ï¼ |
| | | /// </summary> |
| | | /// <param name="keyword">è¾å
¥çå
³é®è¯ï¼å¦ rï¼</param> |
| | | /// <returns>å¹é
çä¾åºåç¼ç å表</returns> |
| | | public async Task<WebResponseContent> SearchSupplierCode(string keyword) |
| | | { |
| | | try |
| | | { |
| | | if (string.IsNullOrWhiteSpace(keyword)) |
| | | return WebResponseContent.Instance.OK("没æå¹é
å°è¯¥ä¾åºåç¼å·"); |
| | | |
| | | var list = await _stockRepository.Db.Queryable<Dt_SupplierInfo>() |
| | | .Where(x => x.SupplierShortName.StartsWith(keyword)) |
| | | .OrderBy(x => x.SupplierShortName) |
| | | .Take(20) |
| | | .Select(x => x.SupplierShortName) |
| | | .ToListAsync(); |
| | | |
| | | return WebResponseContent.Instance.OK(data:list); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// åºåºä»»å¡æ°æ®å¤ç |
| | |
| | | /// <returns></returns> |
| | | public async Task<WebResponseContent> TakeOutbound(List<StockViewDTO> stockViews, string outStation) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | var content = new WebResponseContent(); |
| | | var errorMessages = new List<string>(); |
| | | |
| | | try |
| | | { |
| | | var allFactoryAreas = stockViews.SelectMany(sv => sv.Details) |
| | | .Select(x => x.FactoryArea) |
| | | .GroupBy(x => x) |
| | | .ToList(); |
| | | if (allFactoryAreas.Count >= 2) |
| | | if (stockViews == null || !stockViews.Any()) |
| | | { |
| | | return content.Error($"è¯·éæ©åä¸ååºåºåçåºåè¿è¡çç¹ï¼å½åæ¶å{allFactoryAreas.Count}个ä¸åçååº"); |
| | | content.Error("æªè·åå°åºåæ°æ®"); |
| | | content.Data = new { total = 0, success = 0, fail = 0, failMsg = errorMessages }; |
| | | return content; |
| | | } |
| | | List<int> ids = stockViews.Select(x => x.StockId).ToList(); |
| | | //è·ååºå |
| | | List<Dt_StockInfo> stockInfos = _stockRepository.Db.Queryable<Dt_StockInfo>().Where(x => ids.Contains(x.Id)).Includes(x => x.Details).ToList(); |
| | | if (stockInfos.Count != stockViews.Count) |
| | | |
| | | var ids = stockViews.Select(x => x.StockId).ToList(); |
| | | var stockInfos = _stockRepository.Db.Queryable<Dt_StockInfo>() |
| | | .Where(x => ids.Contains(x.Id)) |
| | | .Includes(x => x.Details) |
| | | .ToList(); |
| | | |
| | | var locCodes = stockInfos.Select(x => x.LocationCode).ToList(); |
| | | var locationInfos = _locationInfoService.Db.Queryable<Dt_LocationInfo>() |
| | | .Where(x => locCodes.Contains(x.LocationCode)) |
| | | .ToList(); |
| | | |
| | | var finalSuccessStocks = new List<Dt_StockInfo>(); |
| | | var finalSuccessLocations = new List<Dt_LocationInfo>(); |
| | | |
| | | foreach (var stock in stockInfos) |
| | | { |
| | | StockViewDTO? stockViewDTO = stockViews.FirstOrDefault(x => !stockInfos.Select(x => x.PalletCode).ToList().Contains(x.PalletCode)); |
| | | return content.Error($"æªæ¾å°{stockViewDTO?.PalletCode}åºå"); |
| | | } |
| | | //è·åè´§ä½ |
| | | List<string> locStrs = stockInfos.Select(x => x.LocationCode).ToList(); |
| | | List<Dt_LocationInfo> locationInfos =_locationInfoService.Db.Queryable<Dt_LocationInfo>().Where(x => locStrs.Contains(x.LocationCode)).ToList(); |
| | | if (stockInfos.Count != locationInfos.Count) |
| | | { |
| | | string? locStr = locStrs.FirstOrDefault(x => !locationInfos.Select(x => x.LocationCode).ToList().Contains(x)); |
| | | return content.Error($"æªæ¾å°{locStr}è´§ä½æ°æ®"); |
| | | } |
| | | Dt_TakeStockOrder takeStockOrder = new Dt_TakeStockOrder() |
| | | { |
| | | WarehouseId = stockInfos.FirstOrDefault().WarehouseId, |
| | | TakeStockStatus = TakeStockStatusEnum.çç¹ä¸.ObjToInt(), |
| | | OrderNo = CreateCodeByRule(nameof(RuleCodeEnum.PDCodeRule)), |
| | | AllPalletCode = string.Join(",", stockInfos.Select(item => item.PalletCode).Where(palletCode => !string.IsNullOrEmpty(palletCode))), |
| | | Remark = outStation |
| | | |
| | | }; |
| | | foreach (var item in stockInfos) |
| | | { |
| | | if (item.Details.Count <= 0) |
| | | try |
| | | { |
| | | return content.Error($"æªæ¾å°{item.PalletCode}åºåæç»æ°æ®"); |
| | | if (stock.Details == null || !stock.Details.Any()) |
| | | { |
| | | errorMessages.Add($"æçã{stock.PalletCode}ãï¼æ åºåæç»"); |
| | | continue; |
| | | } |
| | | |
| | | var loc = locationInfos.FirstOrDefault(x => x.LocationCode == stock.LocationCode); |
| | | if (loc == null) |
| | | { |
| | | errorMessages.Add($"æçã{stock.PalletCode}ãï¼åºä½ä¸åå¨"); |
| | | continue; |
| | | } |
| | | |
| | | if (loc.EnableStatus != EnableStatusEnum.Normal.ObjToInt() || |
| | | loc.LocationStatus != LocationStatusEnum.InStock.ObjToInt() || |
| | | stock.StockStatus != StockStatusEmun.å
¥åºå®æ.ObjToInt()) |
| | | { |
| | | errorMessages.Add($"æçã{stock.PalletCode}ãï¼ç¶æä¸å
许åºåº"); |
| | | continue; |
| | | } |
| | | |
| | | finalSuccessStocks.Add(stock); |
| | | finalSuccessLocations.Add(loc); |
| | | } |
| | | Dt_LocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.LocationCode == item.LocationCode); |
| | | if (locationInfo == null || (locationInfo.EnableStatus == EnableStatusEnum.Disable.ObjToInt() || locationInfo.EnableStatus != EnableStatusEnum.Normal.ObjToInt()) || locationInfo.LocationStatus != LocationStatusEnum.InStock.ObjToInt() || item.StockStatus != StockStatusEmun.å
¥åºå®æ.ObjToInt()) |
| | | catch (Exception ex) |
| | | { |
| | | return content.Error($"{item.PalletCode}è´§ä½æåºåç¶æä¸æ»¡è¶³åºåºæ¡ä»¶"); |
| | | } |
| | | errorMessages.Add($"æçã{stock.PalletCode}ãå¼å¸¸ï¼{ex.Message}"); |
| | | continue; |
| | | } |
| | | } |
| | | List<Dt_Task> tasks = GetTasks(stockInfos, TaskTypeEnum.OutInventory,outStation); |
| | | if (tasks == null || tasks.Count <= 0) |
| | | |
| | | if (finalSuccessStocks.Any()) |
| | | { |
| | | return content.Error($"çæä»»å¡å¤±è´¥"); |
| | | var takeStockOrder = new Dt_TakeStockOrder |
| | | { |
| | | WarehouseId = finalSuccessStocks.First().WarehouseId, |
| | | TakeStockStatus = TakeStockStatusEnum.çç¹ä¸.ObjToInt(), |
| | | OrderNo = CreateCodeByRule(nameof(RuleCodeEnum.PDCodeRule)), |
| | | AllPalletCode = string.Join(",", finalSuccessStocks.Select(x => x.PalletCode)), |
| | | Remark = outStation |
| | | }; |
| | | |
| | | var tasks = GetTasks(finalSuccessStocks, TaskTypeEnum.OutInventory, outStation); |
| | | if (tasks == null || tasks.Count <= 0) |
| | | { |
| | | errorMessages.Add("ä»»å¡çæå¤±è´¥"); |
| | | } |
| | | else |
| | | { |
| | | finalSuccessStocks.ForEach(x => x.StockStatus = StockStatusEmun.çç¹åºåºéå®.ObjToInt()); |
| | | finalSuccessLocations.ForEach(x => x.LocationStatus = LocationStatusEnum.Lock.ObjToInt()); |
| | | tasks.ForEach(x => x.OrderNo = takeStockOrder.OrderNo); |
| | | |
| | | _unitOfWorkManage.BeginTran(); |
| | | _stockRepository.UpdateData(finalSuccessStocks); |
| | | _takeStockOrder.AddData(takeStockOrder); |
| | | BaseDal.AddData(tasks); |
| | | _locationInfoService.UpdateData(finalSuccessLocations); |
| | | _unitOfWorkManage.CommitTran(); |
| | | } |
| | | } |
| | | stockInfos.ForEach(x => |
| | | { |
| | | x.StockStatus = StockStatusEmun.çç¹åºåºéå®.ObjToInt(); |
| | | }); |
| | | tasks.ForEach(x => |
| | | { |
| | | x.OrderNo = takeStockOrder.OrderNo; |
| | | }); |
| | | locationInfos.ForEach(x => |
| | | { |
| | | x.LocationStatus = LocationStatusEnum.Lock.ObjToInt(); |
| | | }); |
| | | _unitOfWorkManage.BeginTran(); |
| | | //æ´æ°åºåç¶æ |
| | | _stockRepository.UpdateData(stockInfos); |
| | | _takeStockOrder.AddData(takeStockOrder); |
| | | //æ°å»ºä»»å¡ |
| | | BaseDal.AddData(tasks); |
| | | _locationInfoService.UpdateData(locationInfos); |
| | | _unitOfWorkManage.CommitTran(); |
| | | content.OK(); |
| | | //TaskModel esstask = new TaskModel() |
| | | //{ |
| | | // taskType = "carry", |
| | | // taskGroupCode = "", |
| | | // groupPriority = 0, |
| | | // tasks = new List<TasksType>() |
| | | //}; |
| | | |
| | | //foreach (var task in tasks) |
| | | //{ |
| | | // esstask. |
| | | // tasks.Add(new TasksType |
| | | // { |
| | | // taskCode = task.TaskNum.ToString(), |
| | | // taskPriority = 0, |
| | | // taskDescribe = new TaskDescribeType |
| | | // { |
| | | // containerCode = task.PalletCode, |
| | | // containerType = "CT_KUBOT_STANDARD", |
| | | // fromLocationCode = task.SourceAddress ?? "", |
| | | // toStationCode = "", |
| | | // toLocationCode = task.TargetAddress, |
| | | // deadline = 0, |
| | | // storageTag = "" |
| | | // } |
| | | // } |
| | | // ); |
| | | //} |
| | | //var result = await _eSSApiService.CreateTaskAsync(esstask); |
| | | |
| | | //_logger.LogInformation("å建任å¡PalletOutboundTask è¿å: " + result); |
| | | //if (result) |
| | | //{ |
| | | // return WebResponseContent.Instance.OK(); |
| | | //} |
| | | //else |
| | | //{ |
| | | // return WebResponseContent.Instance.Error("ä¸åæºå¨äººä»»å¡å¤±è´¥ï¼"); |
| | | //} |
| | | //content.OK(); |
| | | content.OK($"å¤çå®æï¼æåã{finalSuccessStocks.Count}ãæ¡ï¼å¤±è´¥ã{errorMessages.Count}ãæ¡"); |
| | | content.Data = new |
| | | { |
| | | total = stockInfos.Count, |
| | | success = finalSuccessStocks.Count, |
| | | fail = errorMessages.Count, |
| | | failMsg = errorMessages |
| | | }; |
| | | return content; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return await Task.FromResult(WebResponseContent.Instance.Error(ex.Message)); |
| | | content.Error($"ç³»ç»å¼å¸¸ï¼{ex.Message}"); |
| | | content.Data = new |
| | | { |
| | | total = stockViews?.Count ?? 0, |
| | | success = 0, |
| | | fail = 1, |
| | | failMsg = new List<string> { ex.Message } |
| | | }; |
| | | return content; |
| | | } |
| | | return content; |
| | | } |
| | | |
| | | public async Task<WebResponseContent> BatchOutboundByExcel(IFormFile file, string outStation) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | List<StockViewDTO> successStockViews = new List<StockViewDTO>(); |
| | | List<string> noStockMaterialCodes = new List<string>(); |
| | | |
| | | try |
| | | { |
| | | if (file == null || file.Length == 0) |
| | | return content.Error("ä¸ä¼ 失败ï¼è¯·éæ©éè¦å¯¼å
¥çExcelæä»¶"); |
| | | |
| | | var ext = Path.GetExtension(file.FileName).ToLower(); |
| | | if (ext != ".xls" && ext != ".xlsx") |
| | | return content.Error("ä¸ä¼ 失败ï¼ä»
æ¯æ .xls å .xlsx æ ¼å¼çExcelæä»¶ï¼è¯·éæ°ä¸ä¼ "); |
| | | |
| | | try |
| | | { |
| | | using var stream = file.OpenReadStream(); |
| | | var excelList = ReadExcel(stream); |
| | | |
| | | if (!excelList.Any()) |
| | | return content.Error("导å
¥å¤±è´¥ï¼Excelæä»¶ä¸æªè¯»åå°ä»»ä½æææ°æ®"); |
| | | |
| | | foreach (var item in excelList) |
| | | { |
| | | var matchedStocks = _stockRepository.Db.Queryable<Dt_StockInfo>() |
| | | .Includes(x => x.Details) |
| | | .Where(x => |
| | | x.Details.Any(d => |
| | | d.WarehouseCode == item.WarehouseCode |
| | | && d.MaterielCode == item.MaterialCode |
| | | ) |
| | | ) |
| | | .ToList(); |
| | | |
| | | if (matchedStocks.Any()) |
| | | { |
| | | successStockViews.AddRange(matchedStocks.Select(s => new StockViewDTO |
| | | { |
| | | StockId = s.Id |
| | | })); |
| | | } |
| | | else |
| | | { |
| | | noStockMaterialCodes.Add(item.MaterialCode); |
| | | } |
| | | } |
| | | |
| | | // æ§è¡åºåº |
| | | if (successStockViews.Any()) |
| | | { |
| | | var result = await TakeOutbound(successStockViews, outStation); |
| | | return result; |
| | | } |
| | | |
| | | // æ ä»»ä½å¯åºåºæ°æ® |
| | | var msg = "æªæ¥è¯¢å°ä»»ä½å¯åºåºåºå"; |
| | | if (noStockMaterialCodes.Any()) |
| | | { |
| | | msg += $"ï¼æ åºåæå·ï¼{string.Join("ã", noStockMaterialCodes)}"; |
| | | } |
| | | return content.Error(msg); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return content.Error($"Excelè§£æå¤±è´¥ï¼{ex.Message}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return content.Error($"æ¹éåºåºå¤±è´¥ï¼ç³»ç»å¼å¸¸ï¼{ex.Message}"); |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// åæ®çææ¹æ³ |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static List<ExcelInventoryOutboundDto> ReadExcel(Stream stream) |
| | | { |
| | | var list = new List<ExcelInventoryOutboundDto>(); |
| | | |
| | | using (var package = new ExcelPackage(stream)) |
| | | { |
| | | var sheet = package.Workbook.Worksheets.FirstOrDefault(); |
| | | if (sheet == null) return list; |
| | | |
| | | // æ£ç¡®è·åè¡æ° |
| | | int rowCount = sheet.Dimension?.End.Row ?? 0; |
| | | |
| | | // 第2è¡å¼å§è¯» |
| | | for (int row = 2; row <= rowCount; row++) |
| | | { |
| | | string location = sheet.Cells[row, 8].Value?.ToString()?.Trim() ?? ""; |
| | | string materialCode = sheet.Cells[row, 2].Value?.ToString()?.Trim() ?? ""; |
| | | |
| | | if (string.IsNullOrEmpty(location) || string.IsNullOrEmpty(materialCode)) |
| | | continue; |
| | | |
| | | list.Add(new ExcelInventoryOutboundDto |
| | | { |
| | | WarehouseCode = location, |
| | | MaterialCode = materialCode |
| | | }); |
| | | } |
| | | } |
| | | |
| | | return list; |
| | | } |
| | | } |
| | | |
| | | } |