MonthlyCapacityLoadAppService.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. using Business.Core.Utilities;
  2. using Business.Domain;
  3. using Business.Dto;
  4. using Business.EntityFrameworkCore.SqlRepositories;
  5. using Business.SaleForecast;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using Volo.Abp.Application.Services;
  11. using Volo.Abp.DependencyInjection;
  12. using Volo.Abp.Domain.Repositories;
  13. using Volo.Abp.MultiTenancy;
  14. using Volo.Abp.Uow;
  15. namespace Business.SaleForecastManagement
  16. {
  17. /// <summary>
  18. /// 产能分析
  19. /// </summary>
  20. public class MonthlyCapacityLoadAppService : ApplicationService, IMonthlyCapacityLoadAppService, ITransientDependency
  21. {
  22. #region 服务
  23. /// <summary>
  24. /// 物料
  25. /// </summary>
  26. private IRepository<ic_item, long> _ic_item;
  27. /// <summary>
  28. /// 整体需求计划明细
  29. /// </summary>
  30. private ISqlRepository<OverallDemandPlanDtl> _overallDemandPlanDtl;
  31. /// <summary>
  32. /// 生产线明细
  33. /// </summary>
  34. private ISqlRepository<ProdLineDetail> _prodLineDetail;
  35. /// <summary>
  36. /// 工作日历数据
  37. /// </summary>
  38. private ISqlRepository<ShopCalendarWorkCtr> _shopCalendarWorkCtr;
  39. /// <summary>
  40. /// 产线休息时间记录表
  41. /// </summary>
  42. private ISqlRepository<QualityLineWorkDetail> _qualityLineWorkDetail;
  43. /// <summary>
  44. /// 节假日记录表
  45. /// </summary>
  46. private ISqlRepository<HolidayMaster> _holidayMaster;
  47. /// <summary>
  48. /// 月度产能共识主表
  49. /// </summary>
  50. private ISqlRepository<MonthlyProdCapacityMain> _monthlyProdCapacityMain;
  51. /// <summary>
  52. /// 月度产能共识明细表
  53. /// </summary>
  54. private ISqlRepository<MonthlyProdCapacityDtl> _monthlyProdCapacityDtl;
  55. /// <summary>
  56. /// 工作单元
  57. /// </summary>
  58. private readonly IUnitOfWorkManager _unitOfWorkManager;
  59. /// <summary>
  60. /// 日志
  61. /// </summary>
  62. private readonly ICurrentTenant _currentTenant;
  63. /// <summary>
  64. /// 年度生产需求大纲
  65. /// </summary>
  66. private IRepository<YearDemandManagement, long> _yearDemandManagement;
  67. /// <summary>
  68. /// 国内终端预测
  69. /// </summary>
  70. private IRepository<DomesticTerminalFcst, long> _domesticTerminalFcst;
  71. /// <summary>
  72. /// 海外销售预测
  73. /// </summary>
  74. private IRepository<OverseasSaleFcst, long> _overseasSaleFcst;
  75. /// <summary>
  76. /// 平台预测收集
  77. /// </summary>
  78. private IRepository<PlatformFcstCollect, long> _platformFcstCollect;
  79. /// <summary>
  80. /// 标准物料规格型号设置表
  81. /// </summary>
  82. private IRepository<StandardItemModelSet,long> _standardItemModelSet;
  83. /// <summary>
  84. /// 雪花算法
  85. /// </summary>
  86. SnowFlake help = new SnowFlake();
  87. #endregion
  88. #region 构造函数
  89. /// <summary>
  90. /// 构造函数
  91. /// </summary>
  92. public MonthlyCapacityLoadAppService(
  93. IRepository<ic_item, long> ic_item,
  94. ISqlRepository<OverallDemandPlanDtl> overallDemandPlanDtl,
  95. ISqlRepository<ProdLineDetail> prodLineDetail,
  96. ISqlRepository<ShopCalendarWorkCtr> shopCalendarWorkCtr,
  97. ISqlRepository<QualityLineWorkDetail> qualityLineWorkDetail,
  98. ISqlRepository<HolidayMaster> holidayMaster,
  99. ISqlRepository<MonthlyProdCapacityMain> monthlyProdCapacityMain,
  100. ISqlRepository<MonthlyProdCapacityDtl> monthlyProdCapacityDtl,
  101. IUnitOfWorkManager unitOfWorkManager,
  102. ICurrentTenant currentTenant,
  103. IRepository<StandardItemModelSet,long> standardItemModelSet,
  104. IRepository<YearDemandManagement, long> yearDemandManagement,
  105. IRepository<DomesticTerminalFcst, long> domesticTerminalFcst,
  106. IRepository<OverseasSaleFcst, long> overseasSaleFcst,
  107. IRepository<PlatformFcstCollect, long> platformFcstCollect
  108. )
  109. {
  110. _ic_item = ic_item;
  111. _overallDemandPlanDtl = overallDemandPlanDtl;
  112. _prodLineDetail = prodLineDetail;
  113. _shopCalendarWorkCtr = shopCalendarWorkCtr;
  114. _qualityLineWorkDetail = qualityLineWorkDetail;
  115. _holidayMaster = holidayMaster;
  116. _monthlyProdCapacityMain = monthlyProdCapacityMain;
  117. _monthlyProdCapacityDtl = monthlyProdCapacityDtl;
  118. _unitOfWorkManager = unitOfWorkManager;
  119. _currentTenant = currentTenant;
  120. _standardItemModelSet = standardItemModelSet;
  121. _yearDemandManagement= yearDemandManagement;
  122. _domesticTerminalFcst= domesticTerminalFcst;
  123. _overallDemandPlanDtl= overallDemandPlanDtl;
  124. _platformFcstCollect= platformFcstCollect;
  125. }
  126. #endregion
  127. ///// <summary>
  128. ///// 产能分析
  129. ///// </summary>
  130. ///// <param name="input"></param>
  131. ///// <returns></returns>
  132. ///// <exception cref="NotImplementedException"></exception>
  133. //public async Task<string> CapacityAnalysis(InputDto input)
  134. //{
  135. // //1、获取数据
  136. // //1.1 根据年、月、版本号获取整体需求计划明细
  137. // List<OverallDemandPlanDtl> planDtls = _overallDemandPlanDtl.Select(p => p.Year == input.year && p.Month == input.month && p.Version == input.version && p.tenant_id == input.tenant_id && p.factory_id == input.factory_id).OrderBy(p => p.ProdLine).ThenBy(p => p.ProdRange).ThenBy(p => p.Model).ThenBy(p => p.PlanDate).ToList();
  138. // //1.2 根据规格型号获取物料数据
  139. // List<string> models = planDtls.Select(p => p.Model).Distinct().ToList();
  140. // List<StandardItemModelSet> standards = _standardItemModelSet.Select(p => models.Contains(p.Model) && p.tenant_id == input.tenant_id && p.factory_id == input.factory_id);
  141. // //1.3 根据物料编码获取产线数据
  142. // List<ProdLineDetail> lines = _prodLineDetail.Select(p => standards.Select(m => m.ItemNumber).Contains(p.Part) && p.Domain == input.factory_id.ToString() && p.IsActive);
  143. // //1.4 根据产线获取工作日历数据和产线休息配置数据
  144. // List<ShopCalendarWorkCtr> calendars = _shopCalendarWorkCtr.Select(p => lines.Select(m => m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
  145. // List<QualityLineWorkDetail> lineWorks = _qualityLineWorkDetail.Select(p => lines.Select(m => m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
  146. // //1.5 获取当前年和下一年的节假日配置数据
  147. // List<HolidayMaster> holidays = _holidayMaster.Select(p => (p.Dated.Value.Year == input.year || p.Dated.Value.Year == (input.year + 1)) && p.Domain == input.factory_id.ToString() && p.IsActive);
  148. // //月度产能共识主表
  149. // List<MonthlyProdCapacityMain> capacityMains = new List<MonthlyProdCapacityMain>();
  150. // //月度产能共识明细表
  151. // List<MonthlyProdCapacityDtl> capacityDtls = new List<MonthlyProdCapacityDtl>();
  152. // foreach (var item in planDtls)
  153. // {
  154. // //获取当前产品的生产线
  155. // var std = standards.FirstOrDefault(p => p.Model == item.Model);
  156. // if (std == null)
  157. // {
  158. // new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "规格型号【" + item.Model + "】没有维护标准物料数据", _currentTenant.Id.ToString());
  159. // return "NO|规格型号【" + item.Model + "】没有维护标准物料数据,请维护后再发布!";
  160. // }
  161. // var curLines = lines.Where(p => p.Part == std.ItemNumber).OrderBy(p => p.Line).ToList();
  162. // //过滤产线
  163. // var distLines = curLines.Select(p => p.Line).Distinct().ToList();
  164. // if (distLines.Count == 0)
  165. // {
  166. // new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "物料【" + std.ItemNumber + "】没有维护产线数据", _currentTenant.Id.ToString());
  167. // return "NO|物料【" + std.ItemNumber + "】没有维护产线数据,请维护后再发布!";
  168. // }
  169. // foreach (var dl in distLines)
  170. // {
  171. // //添加月度产能共识主表数据
  172. // MonthlyProdCapacityMain main = new MonthlyProdCapacityMain();
  173. // main.Id = help.NextId();
  174. // main.Version = input.version;//整体需求计划版本号
  175. // main.Year = Convert.ToInt16(item.PlanDate.Substring(0, 4));
  176. // main.Month = Convert.ToInt16(item.PlanDate.Substring(4, 2));
  177. // main.ProdRange = item.ProdRange;
  178. // main.Model = item.Model;
  179. // main.ProdQty = item.Qty;
  180. // main.ProdLine = dl;
  181. // main.Qty = item.Qty;
  182. // main.tenant_id = item.tenant_id;
  183. // main.factory_id = item.factory_id;
  184. // main.Version = item.Version;
  185. // main.CreateTime = DateTime.Now;
  186. // capacityMains.Add(main);
  187. // //添加月度产能共识产能效率数据
  188. // MonthlyProdCapacityDtl dtl = new MonthlyProdCapacityDtl();
  189. // dtl.MainId = main.Id;
  190. // dtl.Version = input.version;
  191. // dtl.Year = main.Year;
  192. // dtl.Month = main.Month;
  193. // dtl.ProdLine = dl;
  194. // //计算每天工作时间
  195. // var curCal = calendars.FirstOrDefault(p => p.ProdLine == dl);
  196. // if (curCal == null)
  197. // {
  198. // continue;
  199. // }
  200. // dtl.DailyWorks = curCal.ShiftsHours1;
  201. // dtl.FlightQty = 1;
  202. // //计算当月工作天数
  203. // var curHoildays = holidays.Where(p => p.Dated.Value.Year == main.Year && p.Dated.Value.Month == main.Month).ToList();
  204. // //当月天数
  205. // int days = DateTime.DaysInMonth(main.Year.Value, main.Month.Value);
  206. // //当月周末天数
  207. // int weekDays = CalcWeekDays(days, Convert.ToDateTime(main.Year.ToString() + "-" + main.Month.ToString() + "-01"));
  208. // dtl.YearWorks = days - weekDays - curHoildays.Where(p => p.Ufld1 == "休假").Count() + curHoildays.Where(p => p.Ufld1 == "调班").Count();
  209. // dtl.AvailableTimes = dtl.DailyWorks * dtl.FlightQty * dtl.YearWorks;
  210. // //计算产线耗时
  211. // var line = curLines.Where(p => p.Line == dl).OrderByDescending(p => p.Op).First();
  212. // dtl.NeedWorks = line.Rate == 0 ? 0 : (Math.Ceiling(main.Qty.GetValueOrDefault() / line.Rate));
  213. // dtl.ProdRate = 100;
  214. // dtl.Rate = dtl.AvailableTimes == 0 ? 0 : Math.Floor(dtl.NeedWorks.GetValueOrDefault() / dtl.AvailableTimes.GetValueOrDefault() * 100);
  215. // dtl.IsOverTime = dtl.NeedWorks > dtl.YearWorks ? "是" : "否";
  216. // dtl.OverTimes = dtl.IsOverTime == "是" ? (dtl.NeedWorks - dtl.YearWorks) : 0;
  217. // dtl.tenant_id = main.tenant_id;
  218. // dtl.factory_id = main.factory_id;
  219. // capacityDtls.Add(dtl);
  220. // }
  221. // }
  222. // //保存数据
  223. // using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
  224. // {
  225. // try
  226. // {
  227. // //先删除数据
  228. // _monthlyProdCapacityMain.Delete(p => p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
  229. // _monthlyProdCapacityDtl.Delete(p => p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
  230. // //插入数据
  231. // _monthlyProdCapacityMain.Insert(capacityMains);
  232. // _monthlyProdCapacityDtl.Insert(capacityDtls);
  233. // await unitOfWork.CompleteAsync();
  234. // }
  235. // catch (Exception e)
  236. // {
  237. // unitOfWork.Dispose();
  238. // new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "生成【" + input.year + "年" + input.month + "月】月度产能共识失败:" + e.Message, _currentTenant.Id.ToString());
  239. // return "NO|" + e.Message;
  240. // };
  241. // }
  242. // return "OK|发布成功!";
  243. //}
  244. ///// <summary>
  245. ///// 计算当月有多少个周末
  246. ///// </summary>
  247. ///// <param name="days"></param>
  248. ///// <param name="startDay"></param>
  249. ///// <returns></returns>
  250. //private int CalcWeekDays(int days, DateTime startDay)
  251. //{
  252. // int sumDays = 0;
  253. // for (int i = 0; i < days; i++)
  254. // {
  255. // int weekDays = (int)startDay.AddDays(i).DayOfWeek;
  256. // if (weekDays == 0 || weekDays == 6)
  257. // {
  258. // sumDays++;
  259. // }
  260. // }
  261. // return sumDays;
  262. //}
  263. /// <summary>
  264. /// 月度需求预测更新
  265. /// </summary>
  266. /// <param name="input"></param>
  267. /// <returns></returns>
  268. /// <exception cref="NotImplementedException"></exception>
  269. public async Task<string> DemandAnalysis(InputDto input)
  270. {
  271. //1.0 获取年度生产需求大纲
  272. List<YearDemandManagement> yearDemands = _yearDemandManagement.GetListAsync(p => p.Year == input.year && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
  273. if (yearDemands.Count() == 0)
  274. {
  275. new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("DemandAnalysis", "请导入" + input.year + "年年度生产需求数据后再操作!", _currentTenant.Id.ToString());
  276. return "NO|请导入" + input.year + "年年度生产需求数据后再操作!";
  277. }
  278. //1.1、获取海外销售预测数据
  279. List<OverseasSaleFcst> overseasSales = _overseasSaleFcst.GetListAsync(p => p.Year == input.year && p.Month == input.month && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
  280. if (overseasSales.Count() == 0)
  281. {
  282. new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("DemandAnalysis", "请导入"+input.year+"年"+input.month+"月海外预测数据后再操作!", _currentTenant.Id.ToString());
  283. return "NO|请导入"+input.year+"年"+input.month+"月海外预测数据后再操作!";
  284. }
  285. //1.2、获取平台预测收集数据
  286. List<PlatformFcstCollect> platformFcsts = _platformFcstCollect.GetListAsync(p => p.Year == input.year && p.Month == input.month && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
  287. if (platformFcsts.Count() == 0)
  288. {
  289. new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("DemandAnalysis", "请导入" + input.year + "年" + input.month + "月平台需求预测数据后再操作!", _currentTenant.Id.ToString());
  290. return "NO|请导入" + input.year + "年" + input.month + "月平台需求预测数据后再操作!";
  291. }
  292. //1.3、获取国内终端预测-T1汇总数据
  293. List<DomesticTerminalFcst> domesticFcst = _domesticTerminalFcst.GetListAsync(p => p.Year == input.year && p.Month == input.month && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
  294. if (domesticFcst.Count() == 0)
  295. {
  296. new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("DemandAnalysis", "请导入" + input.year + "年" + input.month + "月国内终端预测数据后再操作!", _currentTenant.Id.ToString());
  297. return "NO|请导入" + input.year + "年" + input.month + "月国内终端预测数据后再操作!";
  298. }
  299. //1.4、根据年度生产大纲,获取规格型号对应的补货周期
  300. List<string> models = yearDemands.Select(p=>p.Model).Distinct().ToList();
  301. List<StandardItemModelSet> standards = _standardItemModelSet.GetListAsync(p=>models.Contains(p.Model) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
  302. //1.5、获取规格型号对应的标准SKU数据
  303. List<string> itemNums = standards.Select(p=>p.ItemNumber).Distinct().ToList();
  304. List<ic_item> items = _ic_item.GetListAsync(p=> itemNums.Contains(p.number) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
  305. //计算海外预测
  306. //保存数据
  307. using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
  308. {
  309. try
  310. {
  311. ////先删除数据
  312. //_monthlyProdCapacityMain.Delete(p => p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
  313. //_monthlyProdCapacityDtl.Delete(p => p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
  314. ////插入数据
  315. //_monthlyProdCapacityMain.Insert(capacityMains);
  316. //_monthlyProdCapacityDtl.Insert(capacityDtls);
  317. //await unitOfWork.CompleteAsync();
  318. }
  319. catch (Exception e)
  320. {
  321. unitOfWork.Dispose();
  322. new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "生成【" + input.year + "年" + input.month + "月】月度产能共识失败:" + e.Message, _currentTenant.Id.ToString());
  323. return "NO|" + e.Message;
  324. };
  325. }
  326. return "OK|发布成功!";
  327. }
  328. }
  329. }