| | |
| | | using AutoMapper; |
| | | using MailKit.Search; |
| | | using Newtonsoft.Json; |
| | | using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Net.Http; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_Common.StockEnum; |
| | |
| | | { |
| | | Dt_StockInfo stockInfo = stockInfos[index]; |
| | | float useableStockQuantity = stockInfo.Details.Where(x => x.MaterielCode == materielCode).Sum(x => x.StockQuantity - x.OutboundQuantity); |
| | | if (useableStockQuantity < needQuantity) |
| | | if (useableStockQuantity < needQuantity && useableStockQuantity>0) |
| | | { |
| | | stockInfo.Details.ForEach(x => x.OutboundQuantity = x.StockQuantity); |
| | | needQuantity -= useableStockQuantity; |
| | |
| | | } |
| | | else |
| | | { |
| | | for (int i = 0; i < stockInfos.Count; i++) |
| | | { |
| | | Dt_StockInfo stockInfo = stockInfos[i]; |
| | | float useableStockQuantity = stockInfo.Details.Where(x => x.MaterielCode == materielCode).Sum(x => x.StockQuantity - x.OutboundQuantity); |
| | | if (useableStockQuantity < needQuantity) |
| | | { |
| | | stockInfo.Details.ForEach(x => x.OutboundQuantity = x.StockQuantity); |
| | | needQuantity -= useableStockQuantity; |
| | | } |
| | | else |
| | | { |
| | | stockInfo.Details.ForEach(x => |
| | | { |
| | | if (x.StockQuantity > x.OutboundQuantity && x.MaterielCode == materielCode) |
| | | { |
| | | if (x.StockQuantity - x.OutboundQuantity >= needQuantity) |
| | | { |
| | | x.OutboundQuantity += needQuantity; |
| | | needQuantity = 0; |
| | | } |
| | | else |
| | | { |
| | | needQuantity -= (x.StockQuantity - x.OutboundQuantity); |
| | | x.OutboundQuantity = x.StockQuantity; |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | outStocks.Add(stockInfo); |
| | | } |
| | | throw new Exception("åºåä¸è¶³"); |
| | | } |
| | | residueQuantity = needQuantity; |
| | | return outStocks; |
| | |
| | | return BaseDal.GetStockInfos(materielCode, batchNo, locationCodes); |
| | | } |
| | | |
| | | public WebResponseContent UpdateExpirationlabel() |
| | | { |
| | | try |
| | | { |
| | | var today = DateTime.Today; |
| | | int batchSize = 1000; |
| | | int totalUpdated = 0; |
| | | int skipCount = 0; |
| | | |
| | | // åªæ¥è¯¢éè¦çåæ®µï¼åå°æ°æ®ä¼ è¾åå
åå ç¨ |
| | | var query = BaseDal.Db.Queryable<Dt_StockInfoDetail>() |
| | | .InnerJoin<Dt_StockInfo>((detail, master) => detail.StockId == master.Id) |
| | | .Select((detail, master) => new |
| | | { |
| | | MasterId = master.Id, |
| | | master.WarehouseId, |
| | | detail.EffectiveDate, |
| | | CurrentExpirationlabel = master.Expirationlabel |
| | | }); |
| | | |
| | | while (true) |
| | | { |
| | | var batchData = query.Skip(skipCount).Take(batchSize).ToList(); |
| | | if (!batchData.Any()) break; |
| | | var groupedData = batchData.GroupBy(item => item.MasterId) |
| | | .Select(g => new |
| | | { |
| | | MasterId = g.Key, |
| | | WarehouseId = g.First().WarehouseId, |
| | | // åææ©çæææ¥æ |
| | | EarliestEffectiveDate = g.Min(item => |
| | | { |
| | | DateTime.TryParse(item.EffectiveDate, out DateTime date); |
| | | return date; |
| | | }), |
| | | CurrentExpirationlabel = g.First().CurrentExpirationlabel |
| | | }) |
| | | .ToList(); |
| | | |
| | | var updateDic = new Dictionary<long, int>(); |
| | | |
| | | foreach (var group in groupedData) |
| | | { |
| | | DateTime effectiveDate = group.EarliestEffectiveDate; |
| | | if (effectiveDate == default(DateTime)) // å¤çè§£æå¤±è´¥çæ
åµ |
| | | { |
| | | Console.WriteLine($"主表ID {group.MasterId} 䏿 æææ¥æï¼è·³è¿"); |
| | | continue; |
| | | } |
| | | |
| | | int newLabel; |
| | | if (effectiveDate < today) |
| | | { |
| | | newLabel = ExpirationlabelEnum.è¿æ.ObjToInt(); |
| | | } |
| | | else if (group.WarehouseId == 3) |
| | | { |
| | | int daysDiff = (effectiveDate - today).Days; |
| | | newLabel = daysDiff < 60 |
| | | ? ExpirationlabelEnum.临æé¢è¦.ObjToInt() |
| | | : ExpirationlabelEnum.æªä¸´æ.ObjToInt(); |
| | | } |
| | | else |
| | | { |
| | | int daysDiff = (effectiveDate - today).Days; |
| | | newLabel = daysDiff < 30 |
| | | ? ExpirationlabelEnum.临æé¢è¦.ObjToInt() |
| | | : ExpirationlabelEnum.æªä¸´æ.ObjToInt(); |
| | | } |
| | | |
| | | if (newLabel != group.CurrentExpirationlabel && !updateDic.ContainsKey(group.MasterId)) |
| | | { |
| | | updateDic[group.MasterId] = newLabel; |
| | | } |
| | | } |
| | | |
| | | if (updateDic.Any()) |
| | | { |
| | | var updateBuilder = BaseDal.Db.Updateable<Dt_StockInfo>(); |
| | | var idsToUpdate = updateDic.Keys.ToList(); |
| | | int updateValue = updateDic.First().Value; |
| | | updateBuilder.SetColumns(m => m.Expirationlabel == updateValue) |
| | | .Where(m => idsToUpdate.Contains(m.Id)); |
| | | |
| | | int batchUpdated = updateBuilder.ExecuteCommand(); |
| | | totalUpdated += batchUpdated; |
| | | |
| | | Console.WriteLine($"æ¹æ¬¡æ´æ°ï¼{batchUpdated} æ¡ï¼ç´¯è®¡æ´æ°ï¼{totalUpdated} æ¡ï¼æ´æ°æ¡ä»¶ï¼{JsonConvert.SerializeObject(idsToUpdate)}"); |
| | | } |
| | | |
| | | skipCount += batchSize; |
| | | } |
| | | |
| | | return WebResponseContent.Instance.OK($"æ´æ°æåï¼å
±æ´æ° {totalUpdated} æ¡è®°å½"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return WebResponseContent.Instance.Error("æ´æ°å¤±è´¥ï¼è¯·è系管çå"); |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// ééæºå¨äººæ¶æ¯æ¨éæµè¯ |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public async Task T0DingTalkText(string webhookUrl, string secret) |
| | | { |
| | | try |
| | | { |
| | | if (webhookUrl == null || secret == null) |
| | | { |
| | | 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 |
| | | { |
| | | msgtype = "text", |
| | | text = new { content = "å°æ´ä¸»äººè¯´: å°æ´è¦åå°å¦å¤©ä¸ç¬¬ä¸ææå¥½" }, |
| | | }; |
| | | 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 errorContent = await response.Content.ReadAsStringAsync(); |
| | | throw new Exception($"ééæ¶æ¯åé失败ï¼ç¶æç : {response.StatusCode}ï¼é误å
容: {errorContent}"); |
| | | } |
| | | } |
| | | catch(Exception ex) |
| | | { |
| | | throw new Exception($"ééæ¶æ¯åé失败ï¼é误å
容: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// çæå ç¾ç¾å |
| | | /// </summary> |
| | | /// <param name="timestamp">æ¶é´æ³</param> |
| | | /// <returns>ç¾å</returns> |
| | | private string GenerateSign(long timestamp,string secret) |
| | | { |
| | | var stringToSign = $"{timestamp}\n{secret}"; |
| | | using (var hmacsha256 = new System.Security.Cryptography.HMACSHA256(Encoding.UTF8.GetBytes(secret))) |
| | | { |
| | | var hashBytes = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)); |
| | | return Convert.ToBase64String(hashBytes).Replace("+", "%2B").Replace("/", "%2F"); |
| | | } |
| | | } |
| | | } |
| | | } |