SxServiceExtension.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using SqlSugar;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Linq;
  6. using wms.dto.response.sx;
  7. using wms.sqlsugar.model.sx;
  8. namespace wms.service.Extensions
  9. {
  10. /// <summary>
  11. /// 时效服务扩展
  12. /// </summary>
  13. public static class SxServiceExtension
  14. {
  15. /// <summary>
  16. /// 装箱时处理焊点盘
  17. /// </summary>
  18. /// <param name="rule">箱号对应的装箱规则</param>
  19. /// <param name="invlist">库存信息</param>
  20. /// <param name="outInvlist">后续可用的不带焊点盘信息</param>
  21. /// <returns>填充后的焊点盘列表</returns>
  22. public static List<StockTemp> ProcessWeldingPointsBoxing(BillPboxrule rule, IEnumerable<StockTemp>? invlist, out IEnumerable<StockTemp>? outInvlist)
  23. {
  24. var solderinvlist = new List<StockTemp>();
  25. invlist ??= Enumerable.Empty<StockTemp>();
  26. // 如果不控制焊点盘数,则直接按生产时间排序后返回
  27. if (rule.SolderMaxCount <= 0)
  28. {
  29. outInvlist = invlist.OrderBy(p => p.ProductTime);
  30. return solderinvlist;
  31. }
  32. // 计算需要获取的焊点盘数量
  33. int itemsPerBox = (rule.SpoolType == "BS60" || rule.SpoolType == "BS40") ? 72 : 36;
  34. int requiredSolderBoxes = Math.Max(0, rule.FullCountQty / itemsPerBox * rule.SolderMaxCount);
  35. // 获取所有带焊点的盘并排序
  36. var availableSolders = invlist.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
  37. // 根据是否管控总焊点数量来选择不同的策略
  38. if (rule.PerSolderMaxCount <= 0)
  39. {
  40. // 不管控总焊点数量,直接取前 N 个
  41. solderinvlist = availableSolders.Take(requiredSolderBoxes).ToList();
  42. }
  43. else
  44. {
  45. // 管控总焊点数量,使用 GetWeldingPointsBoxing 方法
  46. solderinvlist = GetWeldingPointsBoxing(
  47. currentBoxes: solderinvlist,
  48. maxBoxCount: requiredSolderBoxes,
  49. maxTotalSolderCount: rule.PerSolderMaxCount,
  50. inventory: availableSolders
  51. );
  52. }
  53. // 剩余可用库存为无焊点的
  54. outInvlist = invlist.Where(p => p.SolderCount == 0);
  55. return solderinvlist;
  56. }
  57. /// <summary>
  58. /// 获取焊点盘(装箱处理)
  59. /// </summary>
  60. /// <param name="currentBoxes">已有的焊点盘</param>
  61. /// <param name="maxBoxCount">最大焊点盘数</param>
  62. /// <param name="maxTotalSolderCount">最大焊点总数</param>
  63. /// <param name="inventory">库存信息</param>
  64. /// <returns>填充后的焊点盘列表</returns>
  65. public static List<StockTemp> GetWeldingPointsBoxing(List<StockTemp> currentBoxes, int maxBoxCount, int maxTotalSolderCount, IEnumerable<StockTemp>? inventory)
  66. {
  67. if (inventory == null || !inventory.Any()) return currentBoxes;
  68. // 当前状态统计
  69. var currentBoxCount = currentBoxes.Count;
  70. var currentTotalSolderCount = currentBoxes.Sum(x => x.SolderCount);
  71. // 如果已经满载,直接返回
  72. if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) return currentBoxes;
  73. // 将库存转换为列表并排序,避免重复排序
  74. var availableInventory = inventory.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
  75. foreach (var item in availableInventory)
  76. {
  77. // 判断是否还能继续添加
  78. if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) break;
  79. // 添加当前项
  80. currentBoxes.Add(item);
  81. currentBoxCount++;
  82. currentTotalSolderCount += item.SolderCount;
  83. }
  84. return currentBoxes;
  85. }
  86. }
  87. }