ProductExamineAppService.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. using Business.Core.MongoDBHelper;
  2. using Business.ResourceExamineManagement.Dto;
  3. using Business.Model.Production;
  4. using Business.Model.Tech;
  5. using Business.MongoModel.Production;
  6. using Business.MongoModel.Tech;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using Volo.Abp.Application.Services;
  13. using Volo.Abp.Domain.Repositories;
  14. using Business.Dto;
  15. using Business.Model.Sale;
  16. namespace Business.ResourceExamineManagement
  17. {
  18. /// <summary>
  19. /// 产能检查
  20. /// </summary>
  21. public class ProductExamineAppService: ApplicationService
  22. {
  23. #region 服务
  24. /// <summary>
  25. /// 生产线明细表
  26. /// </summary>
  27. public List<ProdLineDetail> prodLines = new List<ProdLineDetail>();
  28. /// <summary>
  29. /// 标准工艺路径表
  30. /// </summary>
  31. public List<RoutingOpDetail> routingOps = new List<RoutingOpDetail>();
  32. /// <summary>
  33. /// 排产记录表
  34. /// </summary>
  35. public List<PeriodSequenceDet> periodSequences = new List<PeriodSequenceDet>();
  36. /// <summary>
  37. /// 工作日历
  38. /// </summary>
  39. public List<ShopCalendarWorkCtr> calendarWorks = new List<ShopCalendarWorkCtr>();
  40. /// <summary>
  41. /// 休息时间段
  42. /// </summary>
  43. public List<QualityLineWorkDetail> qualityLineWorks = new List<QualityLineWorkDetail>();
  44. /// <summary>
  45. /// 节假日
  46. /// </summary>
  47. public List<HolidayMaster> holidays = new List<HolidayMaster>();
  48. #endregion
  49. /// <summary>
  50. /// 构造函数
  51. /// </summary>
  52. public ProductExamineAppService()
  53. {
  54. }
  55. /// <summary>
  56. /// 产能计算-批量
  57. /// </summary>
  58. /// <param name="param">产能检查入参</param>
  59. /// <returns>生产时长(天)</returns>
  60. public DateTime ProductiveExamine(ProdExamineParamDto param)
  61. {
  62. //生产结束时间
  63. DateTime planEnd = param.PlanStart.Date;
  64. if (param.QtyOrd <= 0)
  65. {
  66. return planEnd;
  67. }
  68. //获取当前产品的工艺路线:主产线,最后一道工序
  69. var curRoutingOps = routingOps.Where(p => p.RoutingCode == param.ItemNum && p.ParentOp == 0).OrderByDescending(p => p.Op).ToList();
  70. if (curRoutingOps.Count() == 0)
  71. {
  72. return planEnd;
  73. }
  74. var lastOp = curRoutingOps.First();
  75. //获取产线
  76. var curProdLine = prodLines.FirstOrDefault(p => p.Part == param.ItemNum && p.Op == lastOp.Op);
  77. if (curProdLine == null)
  78. {
  79. return planEnd;
  80. }
  81. //获取产线工作日历
  82. var curCalendars = calendarWorks.Where(p => p.ProdLine == curProdLine.Line).ToList();
  83. if (curCalendars.Count() == 0 || curCalendars.Count() != 7)
  84. {
  85. return planEnd;
  86. }
  87. //获取产线休息时间
  88. var curqualityLines = qualityLineWorks.Where(p=>p.ProdLine == curProdLine.Line).ToList();
  89. //生产数量
  90. decimal sumAmount = 0m;
  91. do
  92. {
  93. //获取工作日
  94. planEnd = GetNextWorkDay(planEnd, curCalendars);
  95. //计算工作日的产能
  96. sumAmount += CalcCapacity(planEnd, curProdLine, curCalendars, curqualityLines);
  97. planEnd = planEnd.AddDays(1);
  98. } while (sumAmount < param.QtyOrd);
  99. return planEnd.AddDays(-1);
  100. }
  101. /// <summary>
  102. /// 获取工作日
  103. /// </summary>
  104. /// <param name="weekDay">当前周几</param>
  105. /// <param name="startTime">开始时间:年-月-日</param>
  106. /// <param name="curCalendars">当前产线的工作日历</param>
  107. /// <returns></returns>
  108. public DateTime GetNextWorkDay(DateTime startTime, List<ShopCalendarWorkCtr> curCalendars)
  109. {
  110. DateTime rtnData = startTime;
  111. int weekDay = (int)startTime.DayOfWeek;
  112. var calendar = curCalendars.FirstOrDefault(p => p.WeekDay == weekDay);
  113. //判断当天是否是工作日
  114. if (weekDay == 0 || weekDay == 6)//周六,周日
  115. {
  116. if (!holidays.Exists(p => p.Dated.GetValueOrDefault().Date == startTime && p.Ufld1 == "调班"))//今天是周末
  117. {
  118. //递归继续找下一个工作日
  119. rtnData = GetNextWorkDay(startTime.AddDays(1), curCalendars);
  120. return rtnData;
  121. }
  122. return rtnData;
  123. }
  124. //今天不是周六周日,需要判断是不是节假日
  125. if (holidays.Exists(p => p.Dated.GetValueOrDefault().Date == startTime && p.Ufld1 == "休假"))//是节假日
  126. {
  127. //递归继续找下一个工作日
  128. rtnData = GetNextWorkDay(startTime.AddDays(1), curCalendars);
  129. return rtnData;
  130. }
  131. return rtnData;
  132. }
  133. /// <summary>
  134. /// 计算当天的产能
  135. /// </summary>
  136. /// <param name="startTime"></param>
  137. /// <param name="prodLine"></param>
  138. /// <param name="curCalendars"></param>
  139. /// <param name="curQualityLines"></param>
  140. /// <returns></returns>
  141. public decimal CalcCapacity(DateTime startTime,ProdLineDetail prodLine, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQualityLines)
  142. {
  143. decimal sumQty = 0m;
  144. //获取休息时长(分钟)
  145. decimal sumResrt = curQualityLines.Sum(p => p.RestTime);
  146. //获取当天的工作时长(分钟)
  147. decimal workTime = curCalendars.First(p => p.WeekDay == (int)startTime.DayOfWeek).ShiftsHours1 * 60;
  148. //计算产能
  149. sumQty = Math.Floor((workTime - sumResrt) / 60 * prodLine.Rate);
  150. return sumQty;
  151. }
  152. /// <summary>
  153. /// 计算订单行的建议交期(产能/物料)
  154. /// </summary>
  155. /// <param name="sentrys"></param>
  156. /// <param name="kittingTimes"></param>
  157. /// <returns></returns>
  158. public void CalcSuggestTime(List<crm_seorderentry> sentrys, List<KittingTimeDto> kittingTimes)
  159. {
  160. ProdExamineParamDto param;
  161. foreach (var item in sentrys)
  162. {
  163. var dto = kittingTimes.FirstOrDefault(p=>p.sentry_id == item.Id);
  164. if (dto == null)
  165. {
  166. continue;
  167. }
  168. if (dto.LackQty == 0)//当前订单行库存足够
  169. {
  170. item.sys_material_date = dto.kitting_time;
  171. item.sys_capacity_date = dto.kitting_time;
  172. }
  173. //计算系统建议交期(物料)
  174. param = new ProdExamineParamDto
  175. {
  176. ItemNum = item.item_number,
  177. QtyOrd = dto.LackQty,
  178. PlanStart = dto.kitting_time.Date.AddDays(1)
  179. };
  180. item.sys_material_date = ProductiveExamine(param);
  181. item.sys_capacity_date = item.sys_material_date;
  182. //计算系统交期(产能)
  183. //获取主线最后一道工序
  184. var routings = routingOps.Where(p => p.RoutingCode == item.item_number && p.ParentOp == 0).OrderBy(p=>p.Op).ToList();
  185. if (routings.Count() == 0)
  186. {
  187. continue;
  188. }
  189. //获取产线
  190. var prodLine = prodLines.FirstOrDefault(p=>p.Part == item.item_number && p.Op == routings.Last().Op);
  191. if (prodLine == null)
  192. {
  193. continue;
  194. }
  195. //获取产线空闲开始时间
  196. var schedules= periodSequences.Where(p => p.ItemNum == item.item_number && p.Op == prodLine.Op && p.Line == prodLine.Line).OrderByDescending(p => p.PlanDate).ToList();
  197. if (schedules.Count() == 0)
  198. {
  199. continue;
  200. }
  201. //产线空闲开始时间
  202. var lastTime = schedules.First().PlanDate.GetValueOrDefault().Date;
  203. if (lastTime >= param.PlanStart)//如果产线空闲时间大于或者等于系统建议交期(物料)的开工时间
  204. {
  205. //取下一天开始计算生产结束时间
  206. param.PlanStart = lastTime.AddDays(1);
  207. item.sys_capacity_date = ProductiveExamine(param);
  208. }
  209. }
  210. }
  211. }
  212. }