| | |
| | | using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Net.Http; |
| | |
| | | while (needQuantity > 0) |
| | | { |
| | | Dt_StockInfo stockInfo = stockInfos[index]; |
| | | float useableStockQuantity = stockInfo.Details.Where(x => x.MaterielCode == materielCode).Sum(x => x.StockQuantity - x.OutboundQuantity); |
| | | if (useableStockQuantity < needQuantity && useableStockQuantity>0) |
| | | // 计ç®å¯ç¨åºåæ¶è½¬æ¢ä¸ºdecimal |
| | | decimal useableStockQuantity = stockInfo.Details |
| | | .Where(x => x.MaterielCode == materielCode) |
| | | .Sum(x => (decimal)x.StockQuantity - (decimal)x.OutboundQuantity); |
| | | |
| | | // å°needQuantity转æ¢ä¸ºdecimalè¿è¡æ¯è¾ |
| | | if (useableStockQuantity < (decimal)needQuantity && useableStockQuantity > 0) |
| | | { |
| | | stockInfo.Details.ForEach(x => x.OutboundQuantity = x.StockQuantity); |
| | | needQuantity -= useableStockQuantity; |
| | | stockInfo.Details.ForEach(x => |
| | | x.OutboundQuantity = x.StockQuantity); |
| | | |
| | | // 使ç¨decimalè¿è¡è®¡ç®åå转åfloat |
| | | needQuantity = (float)((decimal)needQuantity - useableStockQuantity); |
| | | } |
| | | else |
| | | { |
| | |
| | | { |
| | | if (x.StockQuantity > x.OutboundQuantity && x.MaterielCode == materielCode) |
| | | { |
| | | if (x.StockQuantity - x.OutboundQuantity >= needQuantity) |
| | | // å°ç¸å
³å¼è½¬æ¢ä¸ºdecimalè¿è¡ç²¾ç¡®è®¡ç® |
| | | decimal currentStock = (decimal)x.StockQuantity; |
| | | decimal currentOutbound = (decimal)x.OutboundQuantity; |
| | | decimal currentNeed = (decimal)needQuantity; |
| | | decimal available = currentStock - currentOutbound; |
| | | |
| | | if (available >= currentNeed) |
| | | { |
| | | x.OutboundQuantity += needQuantity; |
| | | x.OutboundQuantity = (float)(currentOutbound + currentNeed); |
| | | needQuantity = 0; |
| | | } |
| | | else |
| | | { |
| | | needQuantity -= (x.StockQuantity - x.OutboundQuantity); |
| | | needQuantity = (float)(currentNeed - available); |
| | | x.OutboundQuantity = x.StockQuantity; |
| | | } |
| | | } |
| | |
| | | outStocks.Add(stockInfo); |
| | | index++; |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | |
| | | webhookUrl = "https://oapi.dingtalk.com/robot/send?access_token=fbc3aaf4133ea650d8116fb86b3ebfd0c5e0d46775966ce87893a41886bdf9dc"; |
| | | secret = "SECf221842b26356f22ccac84c4e60714e5287408ee8332a8f63503791382c3f5fb"; |
| | | } |
| | | HttpClient httpClient = new HttpClient(); |
| | | ///è·åæ¶é´æ³ |
| | | var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); |
| | | ///çæç¾å |
| | | var sign = GenerateSign(timestamp,secret); |
| | | // æå»ºè¯·æ±URL |
| | | var url = $"{webhookUrl.Split('?')[0]}?access_token={new Uri(webhookUrl).Query.Split('=')[1]}×tamp={timestamp}&sign={sign}"; |
| | | var requestBody = new |
| | | var warehouseIdToName = new Dictionary<int, string> |
| | | { |
| | | msgtype = "text", |
| | | text = new { content = "å°æ´ä¸»äººè¯´: å°æ´è¦åå°å¦å¤©ä¸ç¬¬ä¸ææå¥½" }, |
| | | { 2, "油墨ä»" }, |
| | | { 3, "æ¿æä»" }, |
| | | { 4, "PPä»" }, |
| | | { 6, "æµè¯æ¶ä»" }, |
| | | { 11, "å¹²èä»" }, |
| | | { 12, "é»çä»" } |
| | | }; |
| | | var jsonBody = JsonConvert.SerializeObject(requestBody); |
| | | var content = new StringContent(jsonBody, Encoding.UTF8, "application/json"); |
| | | |
| | | // åéPOSTè¯·æ± |
| | | var response = await httpClient.PostAsync(url, content); |
| | | if (!response.IsSuccessStatusCode) |
| | | var currentTime = DateTime.Now; |
| | | var ninetyDaysAgo = currentTime.AddDays(-90); |
| | | |
| | | var expirationLabel3Stocks = BaseDal.Db.Queryable<Dt_StockInfo>() |
| | | .Where(s => s.Expirationlabel == 3 && s.WarehouseId != 5) |
| | | .ToList(); |
| | | |
| | | var over90DaysStocks = BaseDal.Db.Queryable<Dt_StockInfo>() |
| | | .Where(s => s.ModifyDate <= ninetyDaysAgo && s.Expirationlabel != 3 && s.WarehouseId != 5) |
| | | .ToList(); |
| | | |
| | | if (!expirationLabel3Stocks.Any() && !over90DaysStocks.Any()) |
| | | { |
| | | // å¤ç请æ±å¤±è´¥çæ
åµ |
| | | var errorContent = await response.Content.ReadAsStringAsync(); |
| | | throw new Exception($"ééæ¶æ¯åé失败ï¼ç¶æç : {response.StatusCode}ï¼é误å
容: {errorContent}"); |
| | | return; |
| | | } |
| | | |
| | | var expirationLabel3StockIds = expirationLabel3Stocks.Select(s => s.Id).ToList(); |
| | | var over90DaysStockIds = over90DaysStocks.Select(s => s.Id).ToList(); |
| | | var expirationLabel3Details = expirationLabel3StockIds.Any() |
| | | ? BaseDal.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(d => expirationLabel3StockIds.Contains(d.StockId)) |
| | | .ToList() |
| | | : new List<Dt_StockInfoDetail>(); |
| | | |
| | | var over90DaysDetails = over90DaysStockIds.Any() |
| | | ? BaseDal.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(d => over90DaysStockIds.Contains(d.StockId)) |
| | | .ToList() |
| | | : new List<Dt_StockInfoDetail>(); |
| | | |
| | | var stockIdToWarehouseId = expirationLabel3Stocks |
| | | .Concat(over90DaysStocks) |
| | | .ToDictionary(s => s.Id, s => s.WarehouseId); |
| | | |
| | | var expirationLabel3Groups = expirationLabel3Details |
| | | .GroupBy(d => stockIdToWarehouseId[d.StockId]) |
| | | .ToDictionary(g => g.Key, g => g.Select(d => new |
| | | { |
| | | d.MaterielCode, |
| | | d.BatchNo |
| | | }).ToList()); |
| | | |
| | | var over90DaysGroups = over90DaysDetails |
| | | .GroupBy(d => stockIdToWarehouseId[d.StockId]) |
| | | .ToDictionary(g => g.Key, g => g.Select(d => new |
| | | { |
| | | d.MaterielCode, |
| | | d.BatchNo |
| | | }).ToList()); |
| | | |
| | | var allWarehouseIds = expirationLabel3Groups.Keys |
| | | .Union(over90DaysGroups.Keys) |
| | | .ToList(); |
| | | |
| | | using (HttpClient httpClient = new HttpClient()) |
| | | { |
| | | foreach (var warehouseId in allWarehouseIds) |
| | | { |
| | | // 9.1 å¤çä»åºåç§°æ¾ç¤ºï¼ä¼å
ç¨æ å°åç§°ï¼æ æ å°æ¶æ¾ç¤ºåå§ID |
| | | var warehouseName = warehouseIdToName.TryGetValue(warehouseId, out var name) |
| | | ? name |
| | | : $"ä»åº{warehouseId}"; |
| | | |
| | | var messageParts = new List<string> |
| | | { |
| | | $"ã{warehouseName}ãç©ææé" |
| | | }; |
| | | |
| | | // æ·»å è¿æç©æä¿¡æ¯ |
| | | if (expirationLabel3Groups.TryGetValue(warehouseId, out var label3Materials) && label3Materials.Any()) |
| | | { |
| | | var label3Details = label3Materials |
| | | .Select(m => $"â¢ ç©æç¼ç ï¼{m.MaterielCode} | æ¹æ¬¡å·ï¼{m.BatchNo}") |
| | | .Aggregate((current, next) => $"{current}\n{next}"); |
| | | messageParts.Add($"ä¸ãè¿æç©æ\n{label3Details}"); |
| | | } |
| | | |
| | | // æ·»å è¶
è¿90天æªä½¿ç¨ç©æä¿¡æ¯ |
| | | if (over90DaysGroups.TryGetValue(warehouseId, out var over90Materials) && over90Materials.Any()) |
| | | { |
| | | var over90Details = over90Materials |
| | | .Select(m => $"â¢ ç©æç¼ç ï¼{m.MaterielCode} | æ¹æ¬¡å·ï¼{m.BatchNo}") |
| | | .Aggregate((current, next) => $"{current}\n{next}"); |
| | | messageParts.Add($"äºãè¶
è¿90天æªä½¿ç¨ç©æ\n{over90Details}"); |
| | | } |
| | | |
| | | var messageContent = string.Join("\n\n", messageParts); |
| | | |
| | | var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); |
| | | var sign = GenerateSign(timestamp, secret); |
| | | |
| | | var url = $"{webhookUrl.Split('?')[0]}?access_token={new Uri(webhookUrl).Query.Split('=')[1]}×tamp={timestamp}&sign={sign}"; |
| | | |
| | | // æå»ºè¯·æ±ä½ï¼ç¬¦åéétextç±»åæ¶æ¯æ ¼å¼ï¼ |
| | | var requestBody = new |
| | | { |
| | | msgtype = "text", |
| | | text = new { content = messageContent } |
| | | }; |
| | | var jsonBody = JsonConvert.SerializeObject(requestBody); |
| | | var content = new StringContent(jsonBody, Encoding.UTF8, "application/json"); |
| | | |
| | | var response = await httpClient.PostAsync(url, content); |
| | | if (!response.IsSuccessStatusCode) |
| | | { |
| | | var errorContent = await response.Content.ReadAsStringAsync(); |
| | | throw new Exception($"ã{warehouseName}ãæ¶æ¯åé失败ï¼ç¶æç ï¼{response.StatusCode}ï¼é误信æ¯ï¼{errorContent}"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch(Exception ex) |
| | | catch (Exception ex) |
| | | { |
| | | throw new Exception($"ééæ¶æ¯åé失败ï¼é误å
容: {ex.Message}"); |
| | | throw new Exception($"ééæ¶æ¯æ¨éæ´ä½å¤±è´¥ï¼é误详æ
ï¼{ex.Message}", ex); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// çæå ç¾ç¾å |
| | | /// </summary> |