GetAvailableEquipmentAppService.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. using Business.Domain;
  2. using Business.EntityFrameworkCore.SqlRepositories;
  3. using Microsoft.CodeAnalysis.CSharp.Syntax;
  4. using Microsoft.EntityFrameworkCore;
  5. using SixLabors.ImageSharp;
  6. using System;
  7. using System.Collections;
  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 Business.Core.Utilities;
  14. using Quartz;
  15. namespace Business.ResourceExamineManagement
  16. {
  17. public class GetAvailableEquipmentAppService : ApplicationService
  18. {
  19. #region 服务
  20. /// <summary>
  21. /// 模具清单
  22. /// </summary>
  23. private ISqlRepository<MoldToolList> _moldToolList;
  24. /// <summary>
  25. /// 设备清单
  26. /// </summary>
  27. private ISqlRepository<EquipmentList> _equipmentList;
  28. // private ISqlRepository<EquipmentUsageLog> _equipmentUsageLog;
  29. /// <summary>
  30. /// 工作日历
  31. /// </summary>
  32. private ISqlRepository<ShopCalendarWorkCtr> _shopCalendarWorkCtr;
  33. /// <summary>
  34. /// 排产结果明细
  35. /// </summary>
  36. private ISqlRepository<ScheduleResultOpMaster> _scheduleResultOpMaster;
  37. /// <summary>
  38. /// Andon 模具异常记录
  39. /// </summary>
  40. private ISqlRepository<sim_andon> _sim_andon;
  41. /// <summary>
  42. /// 人员技能矩阵
  43. /// </summary>
  44. private ISqlRepository<EmpSkills> _EmpSkills;
  45. /// <summary>
  46. /// 产线物料维护
  47. /// </summary>
  48. private ISqlRepository<ProdLineDetail> _ProdLineDetail;
  49. #endregion
  50. #region 构造函数
  51. public GetAvailableEquipmentAppService(
  52. ISqlRepository<MoldToolList> moldToolList,
  53. ISqlRepository<EquipmentList> equipmentList,
  54. ISqlRepository<ShopCalendarWorkCtr> shopCalendarWorkCtr,
  55. ISqlRepository<ScheduleResultOpMaster> scheduleResultOpMaster,
  56. ISqlRepository<sim_andon> sim_andon,
  57. ISqlRepository<EmpSkills> EmpSkills,
  58. ISqlRepository<ProdLineDetail> ProdLineDetail
  59. )
  60. {
  61. _moldToolList = moldToolList;
  62. _equipmentList = equipmentList;
  63. _shopCalendarWorkCtr = shopCalendarWorkCtr;
  64. _scheduleResultOpMaster = scheduleResultOpMaster;
  65. _sim_andon = sim_andon;
  66. _EmpSkills = EmpSkills;
  67. _ProdLineDetail = ProdLineDetail;
  68. }
  69. #endregion
  70. public class Equipment
  71. {
  72. //设备名称
  73. public string MachineName { get; set; }
  74. //资产编码
  75. public string EquipmentAssetID { get; set; }
  76. //设别可用时间
  77. public DateTime AvailableTime { get; set; }
  78. }
  79. public class AvailableEquipmentResult
  80. {
  81. /// <summary>
  82. /// 厂内设备编码
  83. /// </summary>
  84. [Comment("厂内设备编码")]
  85. public string InternalEquipmentCode { get; set; }
  86. /// <summary>
  87. /// 可用设备数量
  88. /// </summary>
  89. [Comment("可用设备数量")]
  90. public decimal AvailableEquipmentCount { get; set; }
  91. /// <summary>
  92. /// 可用设备列表
  93. /// </summary>
  94. [Comment("可用设备列表")]
  95. public List<Equipment> AvailableEquipmentList { get; set; }
  96. }
  97. public class FilterTimeRange
  98. {
  99. //筛选开始时间
  100. public DateTime FilterStartTime { get; set; }
  101. //筛选结束时间
  102. public DateTime FilterEndTime { get; set; }
  103. }
  104. //获取可排产设备
  105. public List<string> GetAvailableEquipment(string InternalEquipmentCode, DateTime? QueryMoment, List<ScheduleResultOpMaster> scheduleMaster)
  106. {
  107. List<string> EquipmentDetails = new List<string>();
  108. if (string.IsNullOrEmpty(InternalEquipmentCode) || QueryMoment == null)
  109. { return new List<string>(); }
  110. if (InternalEquipmentCode.Contains('+')) {
  111. var codes = InternalEquipmentCode.Split('+');
  112. int minAvailableCount = int.MaxValue;
  113. string minEquipmentCode = "";
  114. string minEstimatedMaintenanceReleaseTime = "";
  115. string minStandardRepairDays = "";
  116. var AllavailableEquipmentList = _equipmentList
  117. .Select(p => codes.Contains(p.InternalEquipmentCode) && (p.IsSchedulable == 1 || (p.EstimatedMaintenanceReleaseTime.HasValue && p.EstimatedMaintenanceReleaseTime <= QueryMoment && p.IsSchedulable == 0)))
  118. .ToList();
  119. foreach (var singleCode in codes)
  120. {
  121. var availableEquipmentList = AllavailableEquipmentList.Where(c => c.InternalEquipmentCode == singleCode).ToList();
  122. int availableCount = availableEquipmentList.Count;
  123. // 计算该设备编码的可用设备数量
  124. //for (int i = 0; i < availableEquipmentList.Count; i++)
  125. //{
  126. // if (availableEquipmentList[i].IsSchedulable == 1)
  127. // {
  128. // availableCount++;
  129. // }
  130. // else
  131. // {
  132. // if (availableEquipmentList[i].EstimatedMaintenanceReleaseTime <= QueryMoment)
  133. // {
  134. // availableCount++;
  135. // }
  136. // }
  137. //}
  138. // 查询当前设备编码的已排产设备数量
  139. int usedEquipmentCountForCode = scheduleMaster
  140. .Where(p => p.InternalEquipmentCode == singleCode && QueryMoment >= p.WorkStartTime && QueryMoment < p.WorkEndTime)
  141. .Sum(p => p.DeviceAllocationCount);
  142. // 从该设备编码的可用数量中减去对应的已排产数量
  143. availableCount -= usedEquipmentCountForCode;
  144. availableCount = availableCount < 0 ? 0 : availableCount; // 确保数量不为负
  145. // 更新最小的 AvailableCount
  146. if (availableCount < minAvailableCount)
  147. {
  148. minAvailableCount = availableCount;
  149. var nonSchedulableEquipmentList = availableEquipmentList
  150. .Where(p => p.IsSchedulable == 0 && p.EstimatedMaintenanceReleaseTime.HasValue)
  151. .OrderBy(p => p.EstimatedMaintenanceReleaseTime)
  152. .ToList();
  153. if (nonSchedulableEquipmentList.Count > 0)
  154. {
  155. minEquipmentCode = $"{nonSchedulableEquipmentList[0].InternalEquipmentCode}";
  156. minEstimatedMaintenanceReleaseTime = $"{nonSchedulableEquipmentList[0].EstimatedMaintenanceReleaseTime}";
  157. minStandardRepairDays = $"{nonSchedulableEquipmentList[0].StandardRepairDays}";
  158. }
  159. else
  160. {
  161. minEquipmentCode = " ";
  162. minEstimatedMaintenanceReleaseTime = " ";
  163. minStandardRepairDays = " ";
  164. }
  165. }
  166. }
  167. EquipmentDetails.Add($"{minAvailableCount}");
  168. EquipmentDetails.Add(minEquipmentCode);
  169. EquipmentDetails.Add(minEstimatedMaintenanceReleaseTime);
  170. EquipmentDetails.Add(minStandardRepairDays);
  171. return EquipmentDetails;
  172. }
  173. else
  174. {
  175. var codes = InternalEquipmentCode.Split('/');
  176. var availableEquipmentList = _equipmentList
  177. .Select(p => codes.Contains(p.InternalEquipmentCode) && (p.IsSchedulable == 1 || (p.EstimatedMaintenanceReleaseTime.HasValue && p.EstimatedMaintenanceReleaseTime <= QueryMoment && p.IsSchedulable == 0)))
  178. .ToList();
  179. //int availableCount = _equipmentList
  180. // .Select(p => codes.Contains(p.InternalEquipmentCode) && (p.IsSchedulable == 1 || (p.EstimatedMaintenanceReleaseTime.HasValue && p.EstimatedMaintenanceReleaseTime <= QueryMoment && p.IsSchedulable == 0)))
  181. // .Count();
  182. //for (int i = 0; i < availableEquipmentList.Count; i++)
  183. //{
  184. // if (availableEquipmentList[i].IsSchedulable == 1)
  185. // {
  186. // availableCount++;
  187. // }
  188. // else
  189. // {
  190. // if (availableEquipmentList[i].EstimatedMaintenanceReleaseTime <= QueryMoment)
  191. // {
  192. // availableCount++;
  193. // }
  194. // }
  195. //}
  196. // 查询所有设备编码的已排产设备数量
  197. int usedEquipmentCount = scheduleMaster
  198. .Where(p => p.InternalEquipmentCode == InternalEquipmentCode && QueryMoment >= p.WorkStartTime && QueryMoment < p.WorkEndTime)
  199. .Sum(p => p.DeviceAllocationCount);
  200. int availableCount = availableEquipmentList.Count();
  201. // 从总可用设备数量中减去已排产设备数量
  202. availableCount -= usedEquipmentCount;
  203. availableCount = availableCount <= 0 ? 0 : availableCount;
  204. EquipmentDetails.Add($"{availableCount}");
  205. var nonSchedulableEquipmentList = availableEquipmentList
  206. .Where(p => p.IsSchedulable == 0 && p.EstimatedMaintenanceReleaseTime.HasValue)
  207. .OrderBy(p => p.EstimatedMaintenanceReleaseTime)
  208. .ToList();
  209. if (nonSchedulableEquipmentList.Count <= 0)
  210. {
  211. EquipmentDetails.Add(" ");
  212. EquipmentDetails.Add(" ");
  213. EquipmentDetails.Add(" ");
  214. }
  215. else
  216. {
  217. EquipmentDetails.Add($"{nonSchedulableEquipmentList[0].InternalEquipmentCode}");
  218. EquipmentDetails.Add($"{nonSchedulableEquipmentList[0].EstimatedMaintenanceReleaseTime}");
  219. EquipmentDetails.Add($"{nonSchedulableEquipmentList[0].StandardRepairDays}");
  220. }
  221. return EquipmentDetails;
  222. }
  223. }
  224. //确认时刻所在班组
  225. public FilterTimeRange GetFilterTimeRange(DateTime QueryMoment)
  226. {
  227. var calendars1 = _shopCalendarWorkCtr.Select(p => p.TeamType == 'M' && p.WeekDay == (int)QueryMoment.DayOfWeek).ToList();
  228. FilterTimeRange timeRange = new FilterTimeRange { };
  229. int Qhour = QueryMoment.Hour;
  230. switch (Qhour)
  231. {
  232. //Qhour在当天班组前
  233. case int h when (h < calendars1[0].ShiftsStart1):
  234. int adjustedDayOfWeek = (int)QueryMoment.DayOfWeek - 1;
  235. //周末的衔接
  236. if (adjustedDayOfWeek < 0)
  237. {
  238. adjustedDayOfWeek = 6;
  239. }
  240. var calendars2 = _shopCalendarWorkCtr.Select(p => p.TeamType == 'M' && p.WeekDay == adjustedDayOfWeek).ToList();
  241. int hour = (int)calendars1[0].ShiftsStart2;
  242. int day = QueryMoment.Day - 1;
  243. int month = QueryMoment.Month;
  244. int year = QueryMoment.Year;
  245. // 如果日期减去 1 后小于 1,则需要调整月份和年份
  246. if (day < 1)
  247. {
  248. // 将月份减去 1
  249. month--;
  250. // 如果月份小于 1,则需要将月份设为上一年的 12 月,并将年份减去 1
  251. if (month < 1)
  252. {
  253. month = 12;
  254. year--;
  255. }
  256. // 获取新月份的最后一天,作为新的日期
  257. day = DateTime.DaysInMonth(year, month);
  258. }
  259. DateTime start = new DateTime(
  260. year, // 处理过后的年份
  261. month, // 处理过后的月份
  262. day, // 处理过后的日期
  263. hour, // 小时数
  264. 0, // 分钟数
  265. 0 // 秒数
  266. );
  267. hour = hour + (int)calendars1[0].ShiftsHours2;
  268. DateTime end = new DateTime(
  269. year, // 处理过后的年份
  270. month, // 处理过后的月份
  271. day, // 处理过后的日期
  272. hour, // 小时数
  273. 0, // 分钟数
  274. 0 // 秒数
  275. );
  276. timeRange.FilterStartTime = start;
  277. timeRange.FilterEndTime = end;
  278. break;
  279. //Qhour在当天第一班组内
  280. case int h when (h >= calendars1[0].ShiftsStart1 && h < calendars1[0].ShiftsStart1 + calendars1[0].ShiftsHours1):
  281. start = new DateTime(
  282. QueryMoment.Year, // 处理过后的年份
  283. QueryMoment.Month, // 处理过后的月份
  284. QueryMoment.Day, // 处理过后的日期
  285. (int)calendars1[0].ShiftsStart1, // 小时数
  286. 0, // 分钟数
  287. 0 // 秒数
  288. );
  289. int totalHours = (int)calendars1[0].ShiftsStart1 + (int)calendars1[0].ShiftsHours1;
  290. int extraDays = totalHours / 24; // 计算多出的天数
  291. int adjustedHours = totalHours % 24; // 剩余的小时数
  292. // 计算新的日期,包括跨月份和跨年份的处理
  293. int newDay = QueryMoment.Day + extraDays;
  294. int newMonth = QueryMoment.Month;
  295. int newYear = QueryMoment.Year;
  296. // 处理跨月份的情况
  297. while (newDay > DateTime.DaysInMonth(newYear, newMonth))
  298. {
  299. newDay -= DateTime.DaysInMonth(newYear, newMonth); // 减去当前月的天数
  300. newMonth++; // 增加月份
  301. if (newMonth > 12) // 处理跨年的情况
  302. {
  303. newMonth = 1;
  304. newYear++;
  305. }
  306. }
  307. end = new DateTime(
  308. newYear, // 处理过后的年份
  309. newMonth, // 处理过后的月份
  310. newDay, // 处理过后的日期
  311. adjustedHours, // 调整后的小时数
  312. 0, // 分钟数
  313. 0 // 秒数
  314. );
  315. timeRange.FilterStartTime = start;
  316. timeRange.FilterEndTime = end;
  317. break;
  318. //Qhour在当天第一班组外 ,自动延伸到第二班组
  319. //Qhour在当天第二班组
  320. default:
  321. start = new DateTime(
  322. QueryMoment.Year, // 处理过后的年份
  323. QueryMoment.Month, // 处理过后的月份
  324. QueryMoment.Day, // 处理过后的日期
  325. (int)calendars1[0].ShiftsStart2, // 小时数
  326. 0, // 分钟数
  327. 0 // 秒数
  328. );
  329. totalHours = (int)calendars1[0].ShiftsStart2 + (int)calendars1[0].ShiftsHours2;
  330. extraDays = totalHours / 24; // 计算多出的天数
  331. adjustedHours = totalHours % 24; // 剩余的小时数
  332. // 计算新的日期,包括跨月份和跨年份的处理
  333. newDay = QueryMoment.Day + extraDays;
  334. newMonth = QueryMoment.Month;
  335. newYear = QueryMoment.Year;
  336. // 处理跨月份的情况
  337. while (newDay > DateTime.DaysInMonth(newYear, newMonth))
  338. {
  339. newDay -= DateTime.DaysInMonth(newYear, newMonth); // 减去当前月的天数
  340. newMonth++; // 增加月份
  341. if (newMonth > 12) // 处理跨年的情况
  342. {
  343. newMonth = 1;
  344. newYear++;
  345. }
  346. }
  347. end = new DateTime(
  348. newYear, // 处理过后的年份
  349. newMonth, // 处理过后的月份
  350. newDay, // 处理过后的日期
  351. adjustedHours, // 调整后的小时数
  352. 0, // 分钟数
  353. 0 // 秒数
  354. );
  355. timeRange.FilterStartTime = start;
  356. timeRange.FilterEndTime = end;
  357. break;
  358. }
  359. return timeRange;
  360. }
  361. //获取当前班组的可用设备
  362. public List<string> GetAvailableEquipmentForCurrentTeam(string InternalEquipmentCode, DateTime? QueryMoment, List<ScheduleResultOpMaster> scheduleMaster, string MoldTypeCode=null)
  363. {
  364. //if (string.IsNullOrEmpty(InternalEquipmentCode) || QueryMoment == null)
  365. //{
  366. // return new List<string>() {"-99",$"设备类型编码[{InternalEquipmentCode}]无对应设备,请维护设备台账信息" };
  367. //}
  368. //设备清单中可用于排产的设备
  369. var EquipmentDetails = GetAvailableEquipment(InternalEquipmentCode, QueryMoment, scheduleMaster);
  370. var MoldDetails= GetAvailableMold(MoldTypeCode, QueryMoment, scheduleMaster);
  371. if (MoldDetails.Count > 0 || EquipmentDetails.Count > 0)
  372. {
  373. var mnum = MoldDetails.Count > 0? MoldDetails[0].ToInt():0;
  374. var eqnum = EquipmentDetails.Count > 0? EquipmentDetails[0].ToInt():0;
  375. if (mnum > 0 || eqnum > 0)
  376. {
  377. var AvailableNum = eqnum < mnum ? (eqnum>0? eqnum: mnum) : (mnum>0? mnum: eqnum);
  378. List<string> OpResult = new List<string>();
  379. OpResult.Add($"{AvailableNum}");
  380. OpResult.Add(EquipmentDetails.Count > 0 ? EquipmentDetails[1] :"");
  381. OpResult.Add(EquipmentDetails.Count >= 3 ? EquipmentDetails[2] : "");
  382. OpResult.Add(EquipmentDetails.Count > 3 ? EquipmentDetails[3] : "");
  383. //4-模具数量;5-最早释放模具编码;6-模具释放时间;7-释放数量
  384. OpResult.Add($"{AvailableNum}");
  385. OpResult.Add(MoldDetails.Count > 0 ? MoldDetails[1] : "");
  386. OpResult.Add(MoldDetails.Count >=3 ? MoldDetails[2] : "");
  387. OpResult.Add(MoldDetails.Count > 3 ? MoldDetails[3] : "");
  388. return OpResult;
  389. }
  390. else if (mnum == -99)
  391. {
  392. return MoldDetails;
  393. }
  394. else if (eqnum == -99)
  395. {
  396. return EquipmentDetails;
  397. }
  398. else if(eqnum>0 && mnum==0)
  399. {
  400. return MoldDetails;
  401. }
  402. else { return EquipmentDetails; }
  403. }
  404. else if (!string.IsNullOrEmpty(MoldTypeCode) && (MoldDetails.Count == 0|| MoldDetails.Count<4))
  405. {
  406. return new List<string>() { "-99", $"模具类型编码[{MoldTypeCode}]无对应模具,请维护模具台账信息" };
  407. }
  408. else
  409. {
  410. return EquipmentDetails;
  411. }
  412. }
  413. //获取当前班组的可用模具
  414. public List<string> GetAvailableMold(string MoldTypeCode, DateTime? QueryMoment, List<ScheduleResultOpMaster> scheduleMaster)
  415. {
  416. if (string.IsNullOrEmpty(MoldTypeCode) || QueryMoment == null)
  417. { return new List<string>(); }
  418. string[] MoldTypeCodes;
  419. //筛选该编码的模具清单
  420. if (MoldTypeCode.Contains('/')) { MoldTypeCodes = MoldTypeCode.Split('/'); }
  421. else { MoldTypeCodes = MoldTypeCode.Split('+'); }
  422. var availableMoldList = _moldToolList
  423. .Select(p => MoldTypeCodes.Contains(p.MoldTypeCode)).ToList();
  424. //获得模具数量总数
  425. int TotalMoldCount = availableMoldList.Any() ? availableMoldList[0].MoldCount : 0;
  426. //模具清单无该模具
  427. if (TotalMoldCount == 0) { return new List<string>() { "-99", $"模具类型编码[{MoldTypeCode}]无对应模具,请维护模具台账信息" }; }
  428. int AvailableNum = 0;
  429. int UnAvailableNum = 0;
  430. var scheduleResultOpMaster = scheduleMaster
  431. .Where(p => (p.MoldTypeCode == MoldTypeCode || MoldTypeCodes.Contains(p.MoldTypeCode)) && QueryMoment >= p.WorkStartTime && QueryMoment < p.WorkEndTime)
  432. .ToList();
  433. int UsedMoldCount = scheduleResultOpMaster.Sum(p=>p.MoldAllocationCount);
  434. //for (int i = 0; i < scheduleResultOpMaster.Count; i++)
  435. //{
  436. // if (QueryMoment >= scheduleResultOpMaster[i].WorkStartTime && QueryMoment < scheduleResultOpMaster[i].WorkEndTime)
  437. // {
  438. // UsedMoldCount = UsedMoldCount + scheduleResultOpMaster[i].MoldAllocationCount;
  439. // }
  440. //}
  441. var res = 0;
  442. List<string> MoldResult = new List<string>();
  443. var MoldExceptionHistory = _sim_andon
  444. .Select(p => MoldTypeCodes.Contains( p.Mold)&& p.RestorationTime == null && p.EstimatedMaintenanceReleaseTime1 != null)
  445. .OrderBy(p => p.EstimatedMaintenanceReleaseTime1)
  446. .ToList();
  447. //返回最早开工的模具,内容有 {"可用数量"," 最早释放模具编码","释放时间" ,"释放数量" }
  448. if (MoldExceptionHistory.Count <= 0)
  449. {
  450. DateTime? newDate = QueryMoment?.AddDays(3);
  451. res = TotalMoldCount - UsedMoldCount;
  452. MoldResult.Add($"{res}");
  453. MoldResult.Add($"{MoldTypeCode}");
  454. MoldResult.Add($"{newDate}");
  455. MoldResult.Add("0");
  456. return MoldResult;
  457. }
  458. else
  459. {
  460. //sim_andon模具异常情况记录
  461. for (int i = 0; i < MoldExceptionHistory.Count; i++)
  462. {
  463. //释放时间<=当前时刻,则该时刻模具都可用
  464. if (MoldExceptionHistory[i].EstimatedMaintenanceReleaseTime1 <= QueryMoment)
  465. {
  466. AvailableNum += (int)MoldExceptionHistory[i].ToolRepairQuantity;
  467. }
  468. //释放时间>当前时刻,则要去掉维修模具数量
  469. else
  470. {
  471. UnAvailableNum += (int)MoldExceptionHistory[i].ToolRepairQuantity;
  472. }
  473. }
  474. //返回最早开工的模具,内容有 "可用数量"," 最早释放模具编码","释放时间" ,"释放数量"
  475. res = TotalMoldCount - UnAvailableNum - UsedMoldCount;
  476. MoldResult.Add($"{res}");
  477. MoldResult.Add($"{MoldExceptionHistory[0].Mold}");
  478. MoldResult.Add($"{MoldExceptionHistory[0].EstimatedMaintenanceReleaseTime1}");
  479. MoldResult.Add($"{MoldExceptionHistory[0].ToolRepairQuantity}");
  480. return MoldResult;
  481. }
  482. }
  483. //获取当前可用工人,并对设备 ,模具再分配
  484. public List<string> GetEquipmentCountBySkillRestrictions(string SkillNo, string MoldTypeCode, string InternalEquipmentCode, DateTime? QueryMoment, List<ScheduleResultOpMaster> scheduleMaster,decimal StandardStaffCount)
  485. {
  486. List<string> OpResult = new List<string>();
  487. var AvailableEquipmentCountForCurrentOp = 0;
  488. var equipmentList = GetAvailableEquipmentForCurrentTeam(InternalEquipmentCode, QueryMoment, scheduleMaster, MoldTypeCode);
  489. if (equipmentList.Count > 0) { AvailableEquipmentCountForCurrentOp = equipmentList[0].ToInt(); }
  490. if (AvailableEquipmentCountForCurrentOp > 0)
  491. {
  492. //int RequiredPersonnelForEquipment = ;
  493. var PersonSkillList = _EmpSkills
  494. .Select(p => p.SkillNo == SkillNo && p.SkillLevel > 0 && !string.IsNullOrEmpty(p.EmployeeID))
  495. .OrderByDescending(p => p.SkillLevel)
  496. .ToList();
  497. int employeeCount = PersonSkillList.Count;
  498. var personEmployeeIDs = PersonSkillList.Select(p => p.EmployeeID.ToString()).Distinct().ToList();
  499. Dictionary<string, decimal> totals = new Dictionary<string, decimal>();
  500. personEmployeeIDs.ForEach(x => { totals.Add(x, 0); });
  501. var ProdLineDetail = _ProdLineDetail.Select().ToList();
  502. var scheduleResultOpMaster = scheduleMaster.Where(p => QueryMoment >= p.WorkStartTime && QueryMoment < p.WorkEndTime && !string.IsNullOrEmpty(p.InternalEquipmentCode) && !string.IsNullOrEmpty(p.AssignedEmployeeID)).ToList();
  503. foreach (var schedule in scheduleResultOpMaster)
  504. {
  505. //已排产账号
  506. var assignedEmployeeIDs = schedule.AssignedEmployeeID.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList();
  507. //查询是否包含
  508. var equals = assignedEmployeeIDs.Where(x => personEmployeeIDs.Contains(x)).ToList();
  509. if (equals.Count > 0)
  510. {
  511. var data = ProdLineDetail.FirstOrDefault(p => p.Part == schedule.ItemNum && p.Op == schedule.Op);
  512. if (data != null && data.StandardStaffCount > 0)
  513. {
  514. equals.ForEach(e => {
  515. var scale = data.StandardStaffCount * schedule.DeviceAllocationCount / schedule.AssignedPersonnelCount;
  516. totals[e] += scale;
  517. });
  518. }
  519. }
  520. }
  521. var removes = totals.Where(x => x.Value >= 1 || x.Value + StandardStaffCount > 1).Select(x => x.Key).ToList();
  522. if (removes.Count > 0) personEmployeeIDs.RemoveAll(x => removes.Contains(x));
  523. int RequiredPersonnelForEquipment = (int)Math.Ceiling(AvailableEquipmentCountForCurrentOp * StandardStaffCount);
  524. int AvailablePersonnelForOp = Math.Min(personEmployeeIDs.Count, RequiredPersonnelForEquipment);
  525. if (personEmployeeIDs.Count > RequiredPersonnelForEquipment) RequiredPersonnelForEquipment = AvailableEquipmentCountForCurrentOp;
  526. else RequiredPersonnelForEquipment = (int)(personEmployeeIDs.Count / StandardStaffCount);
  527. string uncountedEmployeeIDString = string.Join("/", personEmployeeIDs);
  528. if (!string.IsNullOrEmpty(MoldTypeCode) && equipmentList.Count>4)
  529. {
  530. OpResult.Add($"{RequiredPersonnelForEquipment}");
  531. OpResult.Add(equipmentList[1]);
  532. OpResult.Add(equipmentList[2]);
  533. OpResult.Add(equipmentList[3]);
  534. //4-模具数量;5-最早释放模具编码;6-模具释放时间;7-释放数量
  535. OpResult.Add($"{RequiredPersonnelForEquipment}");
  536. OpResult.Add(equipmentList[5]);
  537. OpResult.Add(equipmentList[6]);
  538. OpResult.Add(equipmentList[7]);
  539. //8-工序可用人数;9-工人工号字符串
  540. OpResult.Add($"{AvailablePersonnelForOp}");
  541. OpResult.Add($"{uncountedEmployeeIDString}");
  542. return OpResult;
  543. }
  544. else
  545. {
  546. OpResult.Add($"{RequiredPersonnelForEquipment}");
  547. OpResult.Add(equipmentList[1]);
  548. OpResult.Add(equipmentList[2]);
  549. OpResult.Add(equipmentList[3]);
  550. OpResult.Add(" ");
  551. OpResult.Add(" ");
  552. OpResult.Add(" ");
  553. OpResult.Add(" ");
  554. OpResult.Add($"{AvailablePersonnelForOp}");
  555. OpResult.Add($"{uncountedEmployeeIDString}");
  556. return OpResult;
  557. }
  558. }
  559. else
  560. {
  561. return equipmentList;
  562. }
  563. }
  564. }
  565. }