| | |
| | | package com.aps.core.service.impl; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import java.util.*; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import com.aps.common.core.utils.DateUtils; |
| | | import com.aps.common.security.utils.DictUtils; |
| | | import com.aps.common.security.utils.SecurityUtils; |
| | | import com.aps.core.domain.*; |
| | | import com.aps.core.mapper.*; |
| | | import com.aps.core.service.IApsBomService; |
| | | import com.aps.core.service.IApsPlateStandardRequireBomOrderDetailService; |
| | | import com.aps.core.service.IApsPlateStandardRequireBomStockDetailService; |
| | | import com.aps.core.service.*; |
| | | import com.aps.system.api.domain.SysDictData; |
| | | import jakarta.annotation.Resource; |
| | | import com.aps.core.domain.ApsPlateStandardRequire; |
| | | import com.aps.core.mapper.ApsPlateStandardRequireMapper; |
| | | import com.aps.core.service.IApsPlateStandardRequireService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import com.aps.core.service.IApsPlateStandardRequireService; |
| | |
| | | @Resource |
| | | IApsPlateStandardRequireBomOrderDetailService bomOrderDetailService; |
| | | |
| | | @Resource |
| | | IApsStandardProcessRouteLineService routeLineService; |
| | | |
| | | /** |
| | | * 查询钣金工单标准需求 |
| | |
| | | String batchNum=getBatch(); |
| | | /*获取钣金主单信息*/ |
| | | List<ApsPlatePlan> mainPlans = platePlanMapper.selectPlatePlanByPlantMajor(plantCode,mainOrderType); |
| | | List<ApsPlateStandardRequire> requiresList=new ArrayList<>(); |
| | | for (ApsPlatePlan mainPlan : mainPlans) { |
| | | String itemNumber = mainPlan.getItemNumber(); |
| | | /*根据料号 获取BOM Header */ |
| | | /*当前Bom节点处理完成后,处理下级BOM*/ |
| | | List<ApsBom> bomLineList = bomLineService.selectApsBomLineList(plantCode, itemNumber); |
| | | List<ApsPlateStandardRequire> requiresList=new ArrayList<>(); |
| | | if(!bomLineList.isEmpty()){ |
| | | bomLineList.forEach(line -> { |
| | | getBomRequires(plantCode, line, batchNum, null, mainPlan, requiresList, 0L); |
| | | }); |
| | | } |
| | | // 批量插入以提高性能 |
| | | if (!requiresList.isEmpty()) { |
| | | int batchSize = 1000; |
| | | for (int i = 0; i < requiresList.size(); i += batchSize) { |
| | | int end = Math.min(i + batchSize, requiresList.size()); |
| | | List<ApsPlateStandardRequire> batch = requiresList.subList(i, end); |
| | | apsPlateStandardRequireMapper.batchInsert(batch); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | private void getBomRequires(String plant, ApsBom bomLine, String batchNum, Date upLevelStartDate, ApsPlatePlan plan, List<ApsPlateStandardRequire> allRequires, Long level){ |
| | | |
| | | String itemNumber = bomLine.getItemCode(); |
| | | String productivityModel_combined_batch="合批"; |
| | | String productivityModel_monopolize="独占"; |
| | | Optional<ApsStandardProcessRouteHeader> firstProcessRoute = standardProcessRouteHeaderMapper.queryStandardProcessRouteHeaderByPlantAndItemCode(plant, itemNumber).stream().findFirst(); |
| | | if (firstProcessRoute.isPresent()) { |
| | | /*获取工艺路线Header信息*/ |
| | | ApsStandardProcessRouteHeader routeHeader = firstProcessRoute.get(); |
| | | /*构建需求信息*/ |
| | | ApsPlateStandardRequire require = new ApsPlateStandardRequire(); |
| | | require.setId(IdUtil.getSnowflakeNextId()); |
| | | require.setRequireId(plan.getId()); |
| | | require.setBatchNumber(batchNum); |
| | | require.setDocNum(plan.getDocumentNumber()); |
| | | require.setOrgCode(plant); |
| | | require.setBomLineCode(itemNumber); |
| | | require.setBomLineLevel(level); |
| | |
| | | bomStockDetailService.saveStorageAndDetail(storage, plan, bomLine, batchNum, deductionAmount, afterStockAmount); |
| | | } |
| | | } |
| | | /*净需求*/ |
| | | BigDecimal netRequirement = require.getNetRequirement(); |
| | | |
| | | /*工艺路线总需求*/ |
| | | BigDecimal totalRouteTime = getRouteLineTotalTime(routeHeader, productivityModel_monopolize, netRequirement); |
| | | ApsStandardProcessRouteLine routeHeader = routeLineService.getRouteLineTotalTime(require); |
| | | String routeId = routeHeader.getRouteId(); |
| | | BigDecimal totalRouteTime = routeHeader.getRouteTime(); |
| | | long millisecond = 60*60*1000L; |
| | | long totalRouteMillisecond = totalRouteTime.multiply(BigDecimal.valueOf(millisecond)).longValue(); |
| | | require.setProcessRouteId(routeId); |
| | | require.setProcessRouteHours(String.valueOf(totalRouteTime)); |
| | | |
| | | /*完成时间,level=0 时默认为工单的计划完成日期*/ |
| | | Date completeDate= plan.getPlanEndDay(); |
| | | /*预留天数*/ |
| | |
| | | } |
| | | /*设置完成日期*/ |
| | | require.setCompleteDate(completeDate); |
| | | require.setDemandDate(require.getCompleteDate()); |
| | | require.setDemandDate(completeDate); |
| | | /*设置开始时间*/ |
| | | Date startDay = new Date(); |
| | | startDay.setTime(completeDate.getTime() - totalRouteMillisecond); |
| | | require.setStartDate(startDay); |
| | | |
| | | /*计算是否有风险*/ |
| | | require.setHasDelayRisk("无风险"); |
| | | Date dateZero = getDateZero(DateUtils.getNowDate()); |
| | | if (startDay.before(dateZero)) { |
| | | require.setHasDelayRisk("有风险"); |
| | | } |
| | | |
| | | /*生产基地*/ |
| | | require.setProductionBase(plan.getProductionBase()); |
| | | |
| | | require.setMatchState("已匹配"); |
| | | require.setMatchMode("库存匹配"); |
| | | if(require.getNetRequirement().compareTo(BigDecimal.ZERO)>0){ |
| | |
| | | require.setMatchMode("工单匹配"); |
| | | } |
| | | require.setHasDelayRisk("无风险"); |
| | | /*使用子件工单进行需求匹配*/ |
| | | matchRequireAndSubPlan(require); |
| | | |
| | | allRequires.add(require); |
| | | /*当前Bom节点处理完成后,处理下级BOM*/ |
| | |
| | | bomLineList.forEach(line -> { |
| | | getBomRequires(plant, line, batchNum, require.getStartDate(), plan, allRequires, level+1); |
| | | }); |
| | | } |
| | | |
| | | } else { |
| | | throw new RuntimeException("未找到标准工艺路线"); |
| | | } |
| | | } |
| | | |
| | |
| | | ApsMaterialStorageManagement storageParam = new ApsMaterialStorageManagement(); |
| | | storageParam.setItemNumber(itemNumber); |
| | | storageParam.setApplicableFactories(plant); |
| | | Optional<ApsMaterialStorageManagement> firstStorage = itemStorageMapper.selectApsMaterialStorageManagementList(storageParam).stream() |
| | | return itemStorageMapper.selectApsMaterialStorageManagementList(storageParam).stream() |
| | | .findFirst(); |
| | | |
| | | return firstStorage; |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * 使用子件工单匹配需求中的净需求 |
| | | * */ |
| | | |
| | | private void matchRequireAndSubPlan(ApsPlateStandardRequire require) { |
| | | BigDecimal netRequirement = require.getNetRequirement(); |
| | | if (netRequirement.compareTo(BigDecimal.ZERO) > 0) { |
| | | ApsPlatePlan platePlan = apsPlatePlanMapper.selectUnMatchPlateSubPlan(require.getOrgCode()); |
| | | /*子件工单的未匹配数量 作为当前的库存*/ |
| | | while (platePlan != null && netRequirement.compareTo(BigDecimal.ZERO) > 0) { |
| | | BigDecimal stock = platePlan.getUnmatchedQuantity(); |
| | | if (netRequirement.compareTo(stock) < 0) { |
| | | /* 库存数量 大于 净需求数量*/ |
| | |
| | | /*净需求已经被满足,不需要继续匹配*/ |
| | | } |
| | | if (netRequirement.compareTo(stock) > 0) { |
| | | while (platePlan != null && netRequirement.compareTo(BigDecimal.ZERO) > 0) { |
| | | /*需求大于库存*/ |
| | | /*净需求 被部分满足 */ |
| | | BigDecimal rest = netRequirement.subtract(stock); |
| | |
| | | netRequirement = rest; |
| | | } |
| | | } |
| | | |
| | | } |
| | | require.setUnmatchedDemandAmount(require.getNetRequirement()); |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取日期零点 |
| | | * */ |
| | | private Date getDateZero(Date date){ |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | calendar.set(Calendar.MILLISECOND, 0); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | } |