|
|
|
|
@ -81,6 +81,8 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
private final IPersonAbilityService personAbilityService; |
|
|
|
|
private final IEquipResourceService equipResourceService; |
|
|
|
|
private final IPersonResourceService personResourceService; |
|
|
|
|
private final IOutsourceProcessService outsourceProcessService; |
|
|
|
|
private final IProcessSetService processSetService; |
|
|
|
|
|
|
|
|
|
@Value("${business.oldMes.url}") |
|
|
|
|
private String oldMesUrl; |
|
|
|
|
@ -115,7 +117,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
public void scheduling() { |
|
|
|
|
//查询待排产订单,状态是3
|
|
|
|
|
List<YieldOrderEntity> list = |
|
|
|
|
yieldOrderService.list(Wrappers.<YieldOrderEntity>lambdaQuery().eq(BaseEntity::getStatus, YieldOrderEnum.STATUS_APS.getCategory()).isNotNull(YieldOrderEntity::getWorkCenterId).isNotNull(YieldOrderEntity::getReleaseDate)); |
|
|
|
|
yieldOrderService.list(Wrappers.<YieldOrderEntity>lambdaQuery().in(BaseEntity::getStatus, YieldOrderEnum.STATUS_APS.getCategory(),YieldOrderEnum.STATUS_PROCESS_ERROR.getCategory()).isNotNull(YieldOrderEntity::getWorkCenterId).isNotNull(YieldOrderEntity::getReleaseDate)); |
|
|
|
|
log.info("待排产订单数量为:" + list.size()); |
|
|
|
|
if (CollectionUtils.isNotEmpty(list)) { |
|
|
|
|
//校验已排产订单
|
|
|
|
|
@ -133,6 +135,12 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
mainProducerList.forEach(item -> { |
|
|
|
|
mainProducerMap.put(item.getProcessId(), item.getMainProducer()); |
|
|
|
|
}); |
|
|
|
|
//初始化工序
|
|
|
|
|
List<ProcessSetEntity> processList = processSetService.list(); |
|
|
|
|
Map<Long, String> processMap = new HashMap<>(); |
|
|
|
|
processList.forEach(item -> { |
|
|
|
|
processMap.put(item.getId(), item.getName()); |
|
|
|
|
}); |
|
|
|
|
//计算cr值
|
|
|
|
|
calculateCr(list); |
|
|
|
|
//根据作业中心将订单分组,并根据优先级、cr值、订单需求数量、计划下达时间4个维度进行组内排序
|
|
|
|
|
@ -161,7 +169,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
new LinkedBlockingQueue<>(), |
|
|
|
|
r -> new Thread(r, "scheduling-thread-" + System.currentTimeMillis())); |
|
|
|
|
map.forEach((workcenter, orders) -> { |
|
|
|
|
threadPool.execute(() -> allocateResources(orders, personAbilityMap, mainProducerMap, planMap)); |
|
|
|
|
threadPool.execute(() -> allocateResources(orders, personAbilityMap, mainProducerMap, planMap, processMap)); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -322,7 +330,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
* @since 2025/12/1 18:08 |
|
|
|
|
**/ |
|
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
|
public void allocateResources(List<YieldOrderEntity> list, Map<String, PersonAbilityEntity> personAbilityMap, Map<Long, String> mainProducerMap, Map<String, List<WorkPlanEntity>> planMap) { |
|
|
|
|
public void allocateResources(List<YieldOrderEntity> list, Map<String, PersonAbilityEntity> personAbilityMap, Map<Long, String> mainProducerMap, Map<String, List<WorkPlanEntity>> planMap, Map<Long, String> processMap) { |
|
|
|
|
List<WorkOrderEntity> workOrderList = new ArrayList<>(); |
|
|
|
|
for (YieldOrderEntity order : list) { |
|
|
|
|
try { |
|
|
|
|
@ -331,8 +339,10 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
List<WorkPlanEntity> workPlanList = new ArrayList<>(); |
|
|
|
|
//查询所有工序
|
|
|
|
|
List<YieldOrderCraftEntity> craftList = yieldOrderCraftService.list(Wrappers.<YieldOrderCraftEntity>lambdaQuery().eq(YieldOrderCraftEntity::getYoId, order.getId()).ne(YieldOrderCraftEntity::getCaId, 27).orderByAsc(YieldOrderCraftEntity::getProcessNo)); |
|
|
|
|
List<Long> workCenterList = craftList.stream().filter(item -> item.getWorkCenterId() != null).map(YieldOrderCraftEntity::getWorkCenterId).collect(Collectors.toList()); |
|
|
|
|
if (workCenterList.size() != craftList.size()) { |
|
|
|
|
//过滤非外协工序
|
|
|
|
|
List<YieldOrderCraftEntity> craftList1 = craftList.stream().filter(item -> item.getIsOutsource() == false).collect(Collectors.toList()); |
|
|
|
|
List<Long> workCenterList = craftList1.stream().filter(item -> item.getWorkCenterId() != null).map(YieldOrderCraftEntity::getWorkCenterId).collect(Collectors.toList()); |
|
|
|
|
if (workCenterList.size() != craftList1.size()) { |
|
|
|
|
order.setErrorInfo("工序信息不完整,含有未匹配作业中心的工序"); |
|
|
|
|
order.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCategory()); |
|
|
|
|
yieldOrderService.updateById(order); |
|
|
|
|
@ -346,131 +356,169 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
workPlanList = planMap.get(order.getYoCode()); |
|
|
|
|
prevProcessEnd = prevProcessEnd.compareTo(workPlanList.get(workPlanList.size() - 1).getEndTime()) > 0 ? prevProcessEnd : workPlanList.get(workPlanList.size() - 1).getEndTime(); |
|
|
|
|
} |
|
|
|
|
//处理外协工序,外协可能多个工序连续的,共享开始结束时间
|
|
|
|
|
Map<Long,List<YieldOrderCraftEntity>> outSourceMap = craftList.stream().filter(item -> item.getIsOutsource() == true).collect(Collectors.groupingBy(YieldOrderCraftEntity::getOcId)); |
|
|
|
|
Map<Long,String> ppsIdMap = new HashMap<>(); |
|
|
|
|
for (Map.Entry<Long, List<YieldOrderCraftEntity>> entry : outSourceMap.entrySet()) { |
|
|
|
|
String ppsIdStr = entry.getValue().stream() |
|
|
|
|
.map(entity -> String.valueOf(entity.getPpsId())) // long → String
|
|
|
|
|
// 等价写法:.map(entity -> Long.toString(entity.getPpsId()))
|
|
|
|
|
.collect(Collectors.joining(",")); // 逗号分隔拼接
|
|
|
|
|
ppsIdMap.put(entry.getKey(),ppsIdStr); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < craftList.size(); i++) { |
|
|
|
|
YieldOrderCraftEntity craft = craftList.get(i); |
|
|
|
|
if ("设备".equals(mainProducerMap.get(craft.getPpsId()))) { |
|
|
|
|
//根据作业中心查询所有设备
|
|
|
|
|
List<EquipAbilityEntity> equipAbilityList = equipAbilityService.list(Wrappers.<EquipAbilityEntity>lambdaQuery().in(EquipAbilityEntity::getWorkCenterId, craft.getWorkCenterId()).eq(EquipAbilityEntity::getCraftId, craft.getCaId())); |
|
|
|
|
if (CollectionUtils.isEmpty(equipAbilityList)) { |
|
|
|
|
order.setErrorInfo("设备未匹配到对应的设备能力"); |
|
|
|
|
order.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCategory()); |
|
|
|
|
yieldOrderService.updateById(order); |
|
|
|
|
isSchecuding = false; |
|
|
|
|
break; |
|
|
|
|
//如果是外协的话,去查询外协工序时间,若未查询到先默认3天,跳过该工序的排产
|
|
|
|
|
if(craft.getIsOutsource()){ |
|
|
|
|
String ppsIdStr = ppsIdMap.get(craft.getOcId()); |
|
|
|
|
OutsourceProcessEntity outsourceProcess = outsourceProcessService.getOne(Wrappers.<OutsourceProcessEntity>lambdaQuery().eq(OutsourceProcessEntity::getProcessId,ppsIdStr)); |
|
|
|
|
BigDecimal totalTime = new BigDecimal(0); |
|
|
|
|
if(outsourceProcess != null){ |
|
|
|
|
//外协多工序需要把时间平分,方便处理
|
|
|
|
|
prevProcessEnd = prevProcessEnd.plusMinutes((long)((double)outsourceProcess.getDays()/ppsIdStr.split(",").length*24*60)); |
|
|
|
|
totalTime = totalTime.add(BigDecimal.valueOf((long)((double)outsourceProcess.getDays()/ppsIdStr.split(",").length*24*60))); |
|
|
|
|
}else{ |
|
|
|
|
prevProcessEnd = prevProcessEnd.plusDays(3); |
|
|
|
|
totalTime = totalTime.add(BigDecimal.valueOf(3*24*60)); |
|
|
|
|
} |
|
|
|
|
Map<Integer, List<EquipAbilityEntity>> equipAbilityMap = equipAbilityList.stream().collect(Collectors.groupingBy(EquipAbilityEntity::getEquipOrder)); |
|
|
|
|
|
|
|
|
|
//匹配设备资源
|
|
|
|
|
//获取下一个整数点
|
|
|
|
|
LocalDateTime dateTime = getNextIntegerTime(prevProcessEnd); |
|
|
|
|
for (Map.Entry<Integer, List<EquipAbilityEntity>> entry : equipAbilityMap.entrySet()) { |
|
|
|
|
//根据时间点获取所有设备资源
|
|
|
|
|
List<EquipResourceEntity> equipResourceList = equipResourceService.list(Wrappers.<EquipResourceEntity>lambdaQuery().eq(EquipResourceEntity::getCraftId, craft.getCaId()).eq(EquipResourceEntity::getWorkCenterId, craft.getWorkCenterId()).ge(EquipResourceEntity::getStartTime, dateTime).eq(EquipResourceEntity::getIsUsed, 0).in(EquipResourceEntity::getEquipOrder, entry.getKey())); |
|
|
|
|
if (CollectionUtils.isEmpty(equipResourceList)) { |
|
|
|
|
WorkPlanEntity workPlan = new WorkPlanEntity(); |
|
|
|
|
workPlan.setWoId(order.getId()); |
|
|
|
|
workPlan.setCaId(craft.getCaId()); |
|
|
|
|
workPlan.setPpsId(craft.getPpsId()); |
|
|
|
|
workPlan.setWorkQty(order.getYpQty()); |
|
|
|
|
workPlan.setHourQuota(totalTime); |
|
|
|
|
workPlan.setWorkCenterId(craft.getWorkCenterId()); |
|
|
|
|
workPlan.setOrders(craft.getProcessNo()); |
|
|
|
|
workPlan.setOem("0"); |
|
|
|
|
workPlan.setTestQty(0); |
|
|
|
|
workPlan.setQualifiedQty(0); |
|
|
|
|
workPlan.setUnqualifiedQty(0); |
|
|
|
|
workPlan.setScrapQty(0); |
|
|
|
|
workPlanList.add(workPlan); |
|
|
|
|
}else{ |
|
|
|
|
if ("设备".equals(mainProducerMap.get(craft.getPpsId()))) { |
|
|
|
|
//根据作业中心查询所有设备
|
|
|
|
|
List<EquipAbilityEntity> equipAbilityList = equipAbilityService.list(Wrappers.<EquipAbilityEntity>lambdaQuery().in(EquipAbilityEntity::getWorkCenterId, craft.getWorkCenterId()).eq(EquipAbilityEntity::getCraftId, craft.getCaId())); |
|
|
|
|
if (CollectionUtils.isEmpty(equipAbilityList)) { |
|
|
|
|
order.setErrorInfo("工序:"+processMap.get(craft.getPpsId()) +"设备未匹配到对应的设备能力"); |
|
|
|
|
order.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCategory()); |
|
|
|
|
order.setErrorInfo("工序:" + craft.getPpsId() + "未匹配到对应的设备资源"); |
|
|
|
|
yieldOrderService.updateById(order); |
|
|
|
|
isSchecuding = false; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
//设备资源按照时间段分组并按时间排序,然后再每个组内按照剩余产能倒序排序
|
|
|
|
|
Map<LocalDateTime, List<EquipResourceEntity>> equipResourceMap = equipResourceList.stream() |
|
|
|
|
.collect(Collectors.groupingBy( |
|
|
|
|
EquipResourceEntity::getStartTime, // 分组字段:startTime
|
|
|
|
|
// 用TreeMap接收,指定startTime降序(分组的排序)
|
|
|
|
|
TreeMap::new, |
|
|
|
|
// 组内收集器:按restCapacity降序排序
|
|
|
|
|
Collectors.collectingAndThen( |
|
|
|
|
Collectors.toList(), |
|
|
|
|
list1 -> list1.stream() |
|
|
|
|
.sorted(Comparator.comparing( |
|
|
|
|
EquipResourceEntity::getRestCapacity, |
|
|
|
|
// restCapacity 降序比较器(BigDecimal专用)
|
|
|
|
|
Comparator.reverseOrder() |
|
|
|
|
)) |
|
|
|
|
.collect(Collectors.toList()) |
|
|
|
|
) |
|
|
|
|
)); |
|
|
|
|
//计算生产所需产能,需将m2换算成dm2
|
|
|
|
|
BigDecimal sumCapacity = order.getYpArea().multiply(BigDecimal.valueOf(order.getYpQty())); |
|
|
|
|
//需要判断设备额定生产能力是否满足订单总产能,如果不满足,则需要把总产能进行拆分
|
|
|
|
|
List<BigDecimal> capacityList = capacitySplit(equipResourceMap, sumCapacity); |
|
|
|
|
for (BigDecimal capacity : capacityList) { |
|
|
|
|
for (Map.Entry<LocalDateTime, List<EquipResourceEntity>> entry1 : equipResourceMap.entrySet()) { |
|
|
|
|
Boolean isOccupied = false; |
|
|
|
|
List<EquipResourceEntity> resourceList = entry1.getValue(); |
|
|
|
|
for (EquipResourceEntity equipResource : resourceList) { |
|
|
|
|
//如果产能最大的设备都不满足,后面的设备就不需要判断了
|
|
|
|
|
if (equipResource.getRestCapacity().compareTo(capacity) < 0) { |
|
|
|
|
break; |
|
|
|
|
} else { |
|
|
|
|
//生成车间订单
|
|
|
|
|
WorkPlanEntity workPlan = new WorkPlanEntity(); |
|
|
|
|
workPlan.setStartTime(equipResource.getStartTime()); |
|
|
|
|
if (entry.getKey() == 1) { |
|
|
|
|
workPlan.setEndTime(equipResource.getStartTime().plusMinutes(equipResource.getStandardTime().longValue())); |
|
|
|
|
Map<Integer, List<EquipAbilityEntity>> equipAbilityMap = equipAbilityList.stream().collect(Collectors.groupingBy(EquipAbilityEntity::getEquipOrder)); |
|
|
|
|
|
|
|
|
|
//匹配设备资源
|
|
|
|
|
//获取下一个整数点
|
|
|
|
|
LocalDateTime dateTime = getNextIntegerTime(prevProcessEnd); |
|
|
|
|
for (Map.Entry<Integer, List<EquipAbilityEntity>> entry : equipAbilityMap.entrySet()) { |
|
|
|
|
//根据时间点获取所有设备资源
|
|
|
|
|
List<EquipResourceEntity> equipResourceList = equipResourceService.list(Wrappers.<EquipResourceEntity>lambdaQuery().eq(EquipResourceEntity::getCraftId, craft.getCaId()).eq(EquipResourceEntity::getWorkCenterId, craft.getWorkCenterId()).ge(EquipResourceEntity::getStartTime, dateTime).eq(EquipResourceEntity::getIsUsed, 0).in(EquipResourceEntity::getEquipOrder, entry.getKey())); |
|
|
|
|
if (CollectionUtils.isEmpty(equipResourceList)) { |
|
|
|
|
order.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCategory()); |
|
|
|
|
order.setErrorInfo("工序:" + processMap.get(craft.getPpsId()) + "未匹配到对应的设备资源"); |
|
|
|
|
yieldOrderService.updateById(order); |
|
|
|
|
isSchecuding = false; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
//设备资源按照时间段分组并按时间排序,然后再每个组内按照剩余产能倒序排序
|
|
|
|
|
Map<LocalDateTime, List<EquipResourceEntity>> equipResourceMap = equipResourceList.stream() |
|
|
|
|
.collect(Collectors.groupingBy( |
|
|
|
|
EquipResourceEntity::getStartTime, // 分组字段:startTime
|
|
|
|
|
// 用TreeMap接收,指定startTime降序(分组的排序)
|
|
|
|
|
TreeMap::new, |
|
|
|
|
// 组内收集器:按restCapacity降序排序
|
|
|
|
|
Collectors.collectingAndThen( |
|
|
|
|
Collectors.toList(), |
|
|
|
|
list1 -> list1.stream() |
|
|
|
|
.sorted(Comparator.comparing( |
|
|
|
|
EquipResourceEntity::getRestCapacity, |
|
|
|
|
// restCapacity 降序比较器(BigDecimal专用)
|
|
|
|
|
Comparator.reverseOrder() |
|
|
|
|
)) |
|
|
|
|
.collect(Collectors.toList()) |
|
|
|
|
) |
|
|
|
|
)); |
|
|
|
|
//计算生产所需产能,需将m2换算成dm2
|
|
|
|
|
BigDecimal sumCapacity = order.getYpArea().multiply(BigDecimal.valueOf(order.getYpQty())); |
|
|
|
|
//需要判断设备额定生产能力是否满足订单总产能,如果不满足,则需要把总产能进行拆分
|
|
|
|
|
List<BigDecimal> capacityList = capacitySplit(equipResourceMap, sumCapacity); |
|
|
|
|
for (BigDecimal capacity : capacityList) { |
|
|
|
|
for (Map.Entry<LocalDateTime, List<EquipResourceEntity>> entry1 : equipResourceMap.entrySet()) { |
|
|
|
|
Boolean isOccupied = false; |
|
|
|
|
List<EquipResourceEntity> resourceList = entry1.getValue(); |
|
|
|
|
for (EquipResourceEntity equipResource : resourceList) { |
|
|
|
|
//如果产能最大的设备都不满足,后面的设备就不需要判断了
|
|
|
|
|
if (equipResource.getRestCapacity().compareTo(capacity) < 0) { |
|
|
|
|
break; |
|
|
|
|
} else { |
|
|
|
|
workPlan.setEndTime(equipResource.getEndTime()); |
|
|
|
|
//生成车间订单
|
|
|
|
|
WorkPlanEntity workPlan = new WorkPlanEntity(); |
|
|
|
|
workPlan.setStartTime(equipResource.getStartTime()); |
|
|
|
|
if (entry.getKey() == 1) { |
|
|
|
|
workPlan.setEndTime(equipResource.getStartTime().plusMinutes(equipResource.getStandardTime().longValue())); |
|
|
|
|
} else { |
|
|
|
|
workPlan.setEndTime(equipResource.getEndTime()); |
|
|
|
|
} |
|
|
|
|
workPlan.setWorkQty(order.getYpQty()); |
|
|
|
|
workPlan.setCaId(craft.getCaId()); |
|
|
|
|
workPlan.setPpsId(craft.getPpsId()); |
|
|
|
|
workPlan.setMakeTeam(equipResource.getTeamId()); |
|
|
|
|
workPlan.setWorkCenterId(craft.getWorkCenterId()); |
|
|
|
|
workPlan.setOrders(craft.getProcessNo()); |
|
|
|
|
workPlan.setWoId(order.getId()); |
|
|
|
|
workPlan.setOem("0"); |
|
|
|
|
workPlan.setTestQty(0); |
|
|
|
|
workPlan.setQualifiedQty(0); |
|
|
|
|
workPlan.setUnqualifiedQty(0); |
|
|
|
|
workPlan.setScrapQty(0); |
|
|
|
|
workPlan.setHourQuota(BigDecimal.valueOf(ChronoUnit.MINUTES.between(workPlan.getStartTime(), workPlan.getEndTime()))); |
|
|
|
|
workPlan.setEquipCode(equipResource.getEquipCode()); |
|
|
|
|
workPlan.setEquipName(equipResource.getEquipName()); |
|
|
|
|
workPlan.setEquipResourceId(equipResource.getId()); |
|
|
|
|
workPlanList.add(workPlan); |
|
|
|
|
//更新剩余产能
|
|
|
|
|
equipResource.setRestCapacity(equipResource.getRestCapacity().subtract(capacity)); |
|
|
|
|
equipResource.setIsUsed("1"); |
|
|
|
|
//如果剩余产能占总产能不足20%,则修改为已占用
|
|
|
|
|
// if(equipResource.getRestCapacity().divide(equipResource.getTotalCapacity(),2,RoundingMode.HALF_UP).compareTo(BigDecimal.valueOf(0.2)) < 0){
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//同一个设备可能有多个工艺能力,同一时间只能做一个工艺能力的零件,所以需要把当前设备所有工艺能力的剩余产能都更新调
|
|
|
|
|
LambdaUpdateWrapper<EquipResourceEntity> equipWrapper = new LambdaUpdateWrapper<>(); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getEquipCode, equipResource.getEquipCode()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getDateTime, equipResource.getDateTime()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getPeriod, equipResource.getPeriod()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getStartTime, equipResource.getStartTime()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getEndTime, equipResource.getEndTime()); |
|
|
|
|
equipResourceService.update(equipResource, equipWrapper); |
|
|
|
|
//该设备后续所有开始时间小于当前结束时间的时间段都变为不可用
|
|
|
|
|
LambdaUpdateWrapper<EquipResourceEntity> updateWrapper = new LambdaUpdateWrapper(); |
|
|
|
|
updateWrapper.lt(EquipResourceEntity::getStartTime, equipResource.getEndTime()); |
|
|
|
|
updateWrapper.gt(EquipResourceEntity::getStartTime, equipResource.getStartTime()); |
|
|
|
|
updateWrapper.eq(EquipResourceEntity::getEquipCode, equipResource.getEquipCode()); |
|
|
|
|
EquipResourceEntity equipResource1 = new EquipResourceEntity(); |
|
|
|
|
equipResource1.setIsUsed("1"); |
|
|
|
|
equipResourceService.update(equipResource1, updateWrapper); |
|
|
|
|
//当前工序的结束时间作为下一工序的开始时间
|
|
|
|
|
prevProcessEnd = workPlan.getEndTime(); |
|
|
|
|
dateTime = workPlan.getEndTime(); |
|
|
|
|
isOccupied = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
workPlan.setWorkQty(order.getYpQty()); |
|
|
|
|
workPlan.setCaId(craft.getCaId()); |
|
|
|
|
workPlan.setPpsId(craft.getPpsId()); |
|
|
|
|
workPlan.setMakeTeam(equipResource.getTeamId()); |
|
|
|
|
workPlan.setWorkCenterId(craft.getWorkCenterId()); |
|
|
|
|
workPlan.setOrders(craft.getProcessNo()); |
|
|
|
|
workPlan.setWoId(order.getId()); |
|
|
|
|
workPlan.setOem("0"); |
|
|
|
|
workPlan.setTestQty(0); |
|
|
|
|
workPlan.setQualifiedQty(0); |
|
|
|
|
workPlan.setUnqualifiedQty(0); |
|
|
|
|
workPlan.setScrapQty(0); |
|
|
|
|
workPlan.setHourQuota(BigDecimal.valueOf(ChronoUnit.MINUTES.between(workPlan.getStartTime(), workPlan.getEndTime()))); |
|
|
|
|
workPlan.setEquipCode(equipResource.getEquipCode()); |
|
|
|
|
workPlan.setEquipName(equipResource.getEquipName()); |
|
|
|
|
workPlan.setEquipResourceId(equipResource.getId()); |
|
|
|
|
workPlanList.add(workPlan); |
|
|
|
|
//更新剩余产能
|
|
|
|
|
equipResource.setRestCapacity(equipResource.getRestCapacity().subtract(capacity)); |
|
|
|
|
equipResource.setIsUsed("1"); |
|
|
|
|
//如果剩余产能占总产能不足20%,则修改为已占用
|
|
|
|
|
// if(equipResource.getRestCapacity().divide(equipResource.getTotalCapacity(),2,RoundingMode.HALF_UP).compareTo(BigDecimal.valueOf(0.2)) < 0){
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//同一个设备可能有多个工艺能力,同一时间只能做一个工艺能力的零件,所以需要把当前设备所有工艺能力的剩余产能都更新调
|
|
|
|
|
LambdaUpdateWrapper<EquipResourceEntity> equipWrapper = new LambdaUpdateWrapper<>(); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getEquipCode, equipResource.getEquipCode()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getDateTime, equipResource.getDateTime()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getPeriod, equipResource.getPeriod()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getStartTime, equipResource.getStartTime()); |
|
|
|
|
equipWrapper.eq(EquipResourceEntity::getEndTime, equipResource.getEndTime()); |
|
|
|
|
equipResourceService.update(equipResource, equipWrapper); |
|
|
|
|
//该设备后续所有开始时间小于当前结束时间的时间段都变为不可用
|
|
|
|
|
LambdaUpdateWrapper<EquipResourceEntity> updateWrapper = new LambdaUpdateWrapper(); |
|
|
|
|
updateWrapper.lt(EquipResourceEntity::getStartTime, equipResource.getEndTime()); |
|
|
|
|
updateWrapper.gt(EquipResourceEntity::getStartTime, equipResource.getStartTime()); |
|
|
|
|
updateWrapper.eq(EquipResourceEntity::getEquipCode, equipResource.getEquipCode()); |
|
|
|
|
EquipResourceEntity equipResource1 = new EquipResourceEntity(); |
|
|
|
|
equipResource1.setIsUsed("1"); |
|
|
|
|
equipResourceService.update(equipResource1, updateWrapper); |
|
|
|
|
//当前工序的结束时间作为下一工序的开始时间
|
|
|
|
|
prevProcessEnd = workPlan.getEndTime(); |
|
|
|
|
dateTime = workPlan.getEndTime(); |
|
|
|
|
isOccupied = true; |
|
|
|
|
} |
|
|
|
|
if (isOccupied) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (isOccupied) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!isSchecuding) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (!isSchecuding) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else if ("人".equals(mainProducerMap.get(craft.getPpsId()))) { |
|
|
|
|
//匹配人资源
|
|
|
|
|
} else if ("人".equals(mainProducerMap.get(craft.getPpsId()))) { |
|
|
|
|
//匹配人资源
|
|
|
|
|
/* String personAbility = craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId(); |
|
|
|
|
if (personAbilityMap.containsKey(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId())) { |
|
|
|
|
|
|
|
|
|
@ -481,32 +529,32 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
isSchecuding = false; |
|
|
|
|
break; |
|
|
|
|
}*/ |
|
|
|
|
WorkPlanEntity workPlan = new WorkPlanEntity(); |
|
|
|
|
BigDecimal totalTime = new BigDecimal(0); |
|
|
|
|
PersonAbilityEntity ability = personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId()); |
|
|
|
|
//镀后检验和镀后接收先按半小时计算
|
|
|
|
|
if (ability != null) { |
|
|
|
|
if ("镀后检验".equals(ability.getProcessName()) || "镀后接收".equals(ability.getProcessName())) { |
|
|
|
|
totalTime = BigDecimal.valueOf(30); |
|
|
|
|
workPlan.setStartTime(prevProcessEnd.plusMinutes(30)); |
|
|
|
|
workPlan.setEndTime(prevProcessEnd.plusMinutes(60)); |
|
|
|
|
if ("镀后接收".equals(ability.getProcessName())) { |
|
|
|
|
workPlan.setMakeTeam(Long.valueOf(64)); |
|
|
|
|
} |
|
|
|
|
if ("镀后检验".equals(ability.getProcessName())) { |
|
|
|
|
workPlan.setMakeTeam(Long.valueOf(65)); |
|
|
|
|
} |
|
|
|
|
prevProcessEnd = workPlan.getEndTime(); |
|
|
|
|
} else { |
|
|
|
|
if ("0".equals(ability.getType())) { |
|
|
|
|
totalTime = totalTime.add(BigDecimal.valueOf(order.getYpQty()).multiply(ability.getStandardTime()).add(ability.getPrepareTime())); |
|
|
|
|
WorkPlanEntity workPlan = new WorkPlanEntity(); |
|
|
|
|
BigDecimal totalTime = new BigDecimal(0); |
|
|
|
|
PersonAbilityEntity ability = personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId()); |
|
|
|
|
//镀后检验和镀后接收先按半小时计算
|
|
|
|
|
if (ability != null) { |
|
|
|
|
if ("镀后检验".equals(ability.getProcessName()) || "镀后接收".equals(ability.getProcessName())) { |
|
|
|
|
totalTime = BigDecimal.valueOf(30); |
|
|
|
|
workPlan.setStartTime(prevProcessEnd.plusMinutes(30)); |
|
|
|
|
workPlan.setEndTime(prevProcessEnd.plusMinutes(60)); |
|
|
|
|
if ("镀后接收".equals(ability.getProcessName())) { |
|
|
|
|
workPlan.setMakeTeam(Long.valueOf(64)); |
|
|
|
|
} |
|
|
|
|
if ("镀后检验".equals(ability.getProcessName())) { |
|
|
|
|
workPlan.setMakeTeam(Long.valueOf(65)); |
|
|
|
|
} |
|
|
|
|
prevProcessEnd = workPlan.getEndTime(); |
|
|
|
|
} else { |
|
|
|
|
totalTime = totalTime.add(ability.getStandardTime()).add(ability.getPrepareTime()); |
|
|
|
|
if ("0".equals(ability.getType())) { |
|
|
|
|
totalTime = totalTime.add(BigDecimal.valueOf(order.getYpQty()).multiply(ability.getStandardTime()).add(ability.getPrepareTime())); |
|
|
|
|
} else { |
|
|
|
|
totalTime = totalTime.add(ability.getStandardTime()).add(ability.getPrepareTime()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//通过加锁的方式保证每次查询到的人力资源都是最新的
|
|
|
|
|
//通过加锁的方式保证每次查询到的人力资源都是最新的
|
|
|
|
|
/*Long craftId = craft.getCaId(); |
|
|
|
|
Lock craftLock = getCraftLock(craftId); |
|
|
|
|
craftLock.lock(); // 加本地锁,同一工艺ID串行执行
|
|
|
|
|
@ -573,34 +621,30 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
craftLock.unlock(); // 释放本地锁
|
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
//没有人员能力的先默认30分钟
|
|
|
|
|
totalTime = BigDecimal.valueOf(30); |
|
|
|
|
workPlan.setStartTime(prevProcessEnd); |
|
|
|
|
workPlan.setEndTime(prevProcessEnd.plusMinutes(30)); |
|
|
|
|
prevProcessEnd = workPlan.getEndTime(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
workPlan.setWoId(order.getId()); |
|
|
|
|
workPlan.setCaId(craft.getCaId()); |
|
|
|
|
workPlan.setPpsId(craft.getPpsId()); |
|
|
|
|
workPlan.setWorkQty(order.getYpQty()); |
|
|
|
|
workPlan.setHourQuota(totalTime); |
|
|
|
|
workPlan.setWorkCenterId(craft.getWorkCenterId()); |
|
|
|
|
workPlan.setOrders(craft.getProcessNo()); |
|
|
|
|
workPlan.setOem("0"); |
|
|
|
|
workPlan.setTestQty(0); |
|
|
|
|
workPlan.setQualifiedQty(0); |
|
|
|
|
workPlan.setUnqualifiedQty(0); |
|
|
|
|
workPlan.setScrapQty(0); |
|
|
|
|
workPlanList.add(workPlan); |
|
|
|
|
workPlan.setWoId(order.getId()); |
|
|
|
|
workPlan.setCaId(craft.getCaId()); |
|
|
|
|
workPlan.setPpsId(craft.getPpsId()); |
|
|
|
|
workPlan.setWorkQty(order.getYpQty()); |
|
|
|
|
workPlan.setHourQuota(totalTime); |
|
|
|
|
workPlan.setWorkCenterId(craft.getWorkCenterId()); |
|
|
|
|
workPlan.setOrders(craft.getProcessNo()); |
|
|
|
|
workPlan.setOem("0"); |
|
|
|
|
workPlan.setTestQty(0); |
|
|
|
|
workPlan.setQualifiedQty(0); |
|
|
|
|
workPlan.setUnqualifiedQty(0); |
|
|
|
|
workPlan.setScrapQty(0); |
|
|
|
|
workPlanList.add(workPlan); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
//未匹配到设备和人力资源,将工序状态改为6,标识为未排产
|
|
|
|
|
craft.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCategory()); |
|
|
|
|
yieldOrderCraftService.updateById(craft); |
|
|
|
|
} else { |
|
|
|
|
//未匹配到设备和人力资源,将工序状态改为6,标识为未排产
|
|
|
|
|
craft.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCategory()); |
|
|
|
|
yieldOrderCraftService.updateById(craft); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!isSchecuding) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
@ -695,7 +739,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
//根据设备的计划推算其他人力工序的开始结束时间
|
|
|
|
|
public void WorkPlanTimeCalculator(List<WorkPlanEntity> list) { |
|
|
|
|
//根据作业中心分组
|
|
|
|
|
Map<Long, List<WorkPlanEntity>> workPlanMap = list.stream().collect(Collectors.groupingBy(WorkPlanEntity::getWorkCenterId)); |
|
|
|
|
Map<Long, List<WorkPlanEntity>> workPlanMap = list.stream().filter(item -> item.getWorkCenterId() != null).collect(Collectors.groupingBy(WorkPlanEntity::getWorkCenterId)); |
|
|
|
|
for (Map.Entry<Long, List<WorkPlanEntity>> entry : workPlanMap.entrySet()) { |
|
|
|
|
List<WorkPlanEntity> workPlanList = entry.getValue(); |
|
|
|
|
int startIndex = -1; |
|
|
|
|
@ -746,8 +790,19 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO |
|
|
|
|
current.setMakeTeam(prev.getMakeTeam()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < list.size(); i++) { |
|
|
|
|
|
|
|
|
|
//特殊处理,一个作业中心只有人力资源的情况
|
|
|
|
|
for(int i=0;i<list.size();i++){ |
|
|
|
|
if(list.get(i).getStartTime() == null && list.get(i).getEndTime() == null){ |
|
|
|
|
if(i!=0 && list.get(i-1).getEndTime() != null){ |
|
|
|
|
list.get(i).setStartTime(list.get(i-1).getEndTime()); |
|
|
|
|
list.get(i).setEndTime(list.get(i).getStartTime().plusMinutes(list.get(i).getHourQuota().longValue())); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if(i!=list.size()-1 && list.get(i+1).getStartTime() != null){ |
|
|
|
|
list.get(i).setEndTime(list.get(i+1).getStartTime()); |
|
|
|
|
list.get(i).setStartTime(list.get(i).getEndTime().minusMinutes(list.get(i).getHourQuota().longValue())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|