package com.chinaztt.mes.production.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.chinaztt.mes.basic.entity.*; import com.chinaztt.mes.basic.mapper.JoinStepTemplateMapper; import com.chinaztt.mes.basic.mapper.PartMapper; import com.chinaztt.mes.basic.mapper.StaffMapper; import com.chinaztt.mes.basic.mapper.WorkstationLocationMapper; import com.chinaztt.mes.basic.service.PartService; import com.chinaztt.mes.basic.service.WorkstationService; import com.chinaztt.mes.basic.util.BigDecimalUtils; import com.chinaztt.mes.basic.util.RedisUtils; import com.chinaztt.mes.common.constant.Constant; import com.chinaztt.mes.common.handler.StateMachineHandler; import com.chinaztt.mes.common.numgen.NumberGenerator; import com.chinaztt.mes.common.util.StateResult; import com.chinaztt.mes.common.wrapper.QueryWrapperUtil; import com.chinaztt.mes.plan.dto.ManufacturingOrderDTO; import com.chinaztt.mes.plan.dto.ManufacturingOrderSnGenerateDTO; import com.chinaztt.mes.plan.entity.*; import com.chinaztt.mes.plan.mapper.*; import com.chinaztt.mes.plan.service.ManufacturingOrderSnGenerateService; import com.chinaztt.mes.production.dto.*; import com.chinaztt.mes.production.entity.*; import com.chinaztt.mes.production.excel.ProductOutPutData; import com.chinaztt.mes.production.mapper.*; import com.chinaztt.mes.production.service.ProductMainService; import com.chinaztt.mes.production.service.ProductOutputService; import com.chinaztt.mes.production.state.operationtask.constant.OperationTaskStateStringValues; import com.chinaztt.mes.production.state.productmain.ProductMainStateMachineConfig; import com.chinaztt.mes.production.state.productmain.constant.ProductMainEvents; import com.chinaztt.mes.production.state.productmain.constant.ProductMainStateStringValues; import com.chinaztt.mes.production.state.productmain.constant.ProductMainStates; import com.chinaztt.mes.production.state.productout.ProductOutStateMachineConfig; import com.chinaztt.mes.production.state.productout.constant.ProductOutEvents; import com.chinaztt.mes.production.state.productout.constant.ProductOutStateStringValues; import com.chinaztt.mes.production.state.productout.constant.ProductOutStates; import com.chinaztt.mes.production.util.BackUtils; import com.chinaztt.mes.production.util.FeedingUtils; import com.chinaztt.mes.production.util.PrintUrlUtils; import com.chinaztt.mes.production.util.RedisHelper; import com.chinaztt.mes.quality.dto.ApplyDTO; import com.chinaztt.mes.quality.dto.ApplyPartDTO; import com.chinaztt.mes.quality.entity.Apply; import com.chinaztt.mes.quality.entity.ApplyPart; import com.chinaztt.mes.quality.entity.Result; import com.chinaztt.mes.quality.mapper.ApplyMapper; import com.chinaztt.mes.quality.mapper.ApplyPartMapper; import com.chinaztt.mes.quality.mapper.ResultMapper; import com.chinaztt.mes.quality.service.ApplyService; import com.chinaztt.mes.technology.dto.StepDTO; import com.chinaztt.mes.technology.entity.OperationJoinStep; import com.chinaztt.mes.technology.entity.Step; import com.chinaztt.mes.technology.mapper.OperationJoinStepMapper; import com.chinaztt.mes.technology.mapper.RoutingOperationMapper; import com.chinaztt.mes.technology.mapper.StepMapper; import com.chinaztt.mes.warehouse.dto.StockDTO; import com.chinaztt.mes.warehouse.entity.Stock; import com.chinaztt.mes.warehouse.mapper.StockMapper; import com.chinaztt.mes.warehouse.util.StockUtils; import com.chinaztt.mes.warehouse.util.TransactionType; import com.chinaztt.ztt.admin.api.feign.RemoteParamService; import com.chinaztt.ztt.common.core.constant.SecurityConstants; import com.chinaztt.ztt.common.core.util.R; import com.chinaztt.ztt.common.security.util.SecurityUtils; import com.chinaztt.ztt.common.sequence.sequence.Sequence; import com.google.gson.Gson; import com.thoughtworks.xstream.core.BaseException; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; import org.springframework.beans.BeanUtils; import org.springframework.core.env.Environment; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; import org.springframework.statemachine.config.StateMachineFactory; import org.springframework.statemachine.persist.StateMachinePersister; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; /** * 报工主表 * * @author cxf * @date 2020-11-17 10:12:27 */ @Service @Slf4j @AllArgsConstructor @Transactional(rollbackFor = Exception.class) public class ProductMainServiceImpl extends ServiceImpl implements ProductMainService { private static final String OUTPUT_LENGTH_LIMIT = "OUTPUT_LENGTH_LIMIT"; private static final String OUTPUT_UNIT_LIMIT = "OUTPUT_UNIT_LIMIT"; private ArtificialInformationMapper artificialInformationMapper; private ApplyPartMapper applyPartMapper; private ApplyMapper applyMapper; private ApplyService applyService; private BackUtils backUtils; private DutyRecordMapper dutyRecordMapper; private FeedingMapper feedingMapper; private FeedingUtils feedingUtils; private HandymanTypeMapper handymanTypeMapper; private NumberGenerator productMainNumberGenerator; private NumberGenerator productOutputNumberGenerator; private OperationTaskServiceImpl operationTaskService; private OperationTaskMaterialMapper operationTaskMaterialMapper; private OperationTaskProduceMapper operationTaskProduceMapper; private OperationTaskMapper operationTaskMapper; private PartService partService; private PersonBoardMapper personBoardMapper; private ProductInputMapper productInputMapper; private ProductOutputMapper productOutputMapper; private ProductOutputStaffMapper productOutputStaffMapper; private ProductStepMapper productStepMapper; private ProductStepStaffMapper productStepStaffMapper; private ResultMapper resultMapper; private StateMachineFactory productMainStateMachineFactory; private StateMachinePersister persister; private StateMachineFactory productOutStateMachineFactory; private StateMachinePersister productOutPersister; private StaffMapper staffMapper; private StepMapper stepMapper; private StockMapper stockMapper; private StockUtils stockUtils; private WorkstationService workstationService; private WorkstationLocationMapper workstationLocationMapper; private ManufacturingOrderMapper manufacturingOrderMapper; private MoStructureComponentMapper moStructureComponentMapper; private RoutingOperationMapper routingOperationMapper; private MoRoutingOperationMapper moRoutingOperationMapper; private final PrintUrlUtils printUrlUtils; private MouldRegisterMapper mouldRegisterMapper; private MouldUseRecordMapper mouldUseRecordMapper; private OperationJoinStepMapper operationJoinStepMapper; private RemoteParamService remoteParamService; private JoinStepTemplateMapper joinStepTemplateMapper; private OperationTaskRecordMapper operationTaskRecordMapper; private MasterProductionScheduleTheoryQuantityMapper theoryQuantityMapper; private ManufacturingOrderSnGenerateMapper manufacturingOrderSnGenerateMapper; private CustomerOrderMapper customerOrderMapper; private RedisHelper redisHelper; private ProductMainMapper productMainMapper; private ExaminerMapper examinerMapper; private PartMapper partMapper; private ProductOutputService productOutputService; private RedisUtils redisUtils; private ManufacturingOrderSnGenerateService manufacturingOrderSnGenerateService; private Sequence sequence; private final static String WORKBENCH_LABEL_REPRINT = "WORKBENCH_LABEL_REPRINT"; private Environment environment; @Override public ProductMainDTO getProductMainById(Long id) { ProductMainDTO productMainDTO = new ProductMainDTO(); // 1.查投入 productMainDTO.setProductInputList(productInputMapper.queryList(id, null)); // 2.查产出 productMainDTO.setProductOutputList(productOutputMapper.getByMainId(id)); return productMainDTO; } @Override public IPage getProductionProgress(Page page, QueryWrapper gen) { return productOutputMapper.getProductionProgress(page, gen); } @Override public R changeState(Long id, String event) { synchronized (String.valueOf(id).intern()) { ProductMain productMain = baseMapper.selectById(id); Boolean lock = redisHelper.lock("productMain:submit:" + productMain.getId()); if (BooleanUtil.isFalse(lock)) { throw new RuntimeException("报工单正在处理中,请稍后再试"); } try { log.info("报工单:" + productMain.getProductNo() + "报工单更改状态" + event); Message message = MessageBuilder.withPayload(ProductMainEvents.valueOf(event)).setHeader("productMain", productMain).build(); StateMachineHandler handler = new StateMachineHandler(productMainStateMachineFactory, persister, ProductMainStateMachineConfig.MACHINE_ID, productMain); StateResult res = handler.sendEvent(message, productMain.getId()); if (res.isSuccess()) { // // 同步ERP 报工单 TODO // // List productInputDTOS = productInputMapper.queryList(id, null); // reportWork(productMain,productInputDTOS); return R.ok(); } else { throw new RuntimeException(res.getMsg()); } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } finally { redisHelper.delLock("productMain:submit:" + productMain.getId()); } } } private R reportWork(ProductMain productMain, List productInputDTOS) { CloseableHttpClient httpClient = HttpClientBuilder.create().build(); String syncErpUrl = environment.getProperty("reportWork"); HttpPost httpPost = new HttpPost(syncErpUrl); // 将参数转换为JSON字符串 Map params = new HashMap<>(); SaveProcedureProgresEntity saveProcedureProgresEntity = new SaveProcedureProgresEntity(); BigDecimal num = new BigDecimal(0); for (ProductInputDTO bean:productInputDTOS ) { // num.add(bean.get) } // saveProcedureProgresEntity.setNum(); String jsonParams = new Gson().toJson(params); // 设置请求体为JSON格式 StringEntity requestEntity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON); httpPost.setEntity(requestEntity); String responseString = null; CloseableHttpResponse response = null; try { response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); responseString = EntityUtils.toString(entity, "UTF-8"); return new Gson().fromJson(responseString, R.class); } catch (IOException e) { e.printStackTrace(); } return R.failed(); } @Override public List getProductOutPutById(Long id) { return productOutputMapper.getProductOutPutById(id); } @Override public boolean cancelProductMainById(Long id) { // 1.查询报工记录 ProductMain productMain = baseMapper.selectById(id); // 校验是否存在交班产出,若交班产出被使用无法删除 List shiftList = productOutputMapper.selectList(Wrappers.lambdaQuery() .eq(ProductOutput::getProductMainId, id) .eq(ProductOutput::getState, ProductOutStateStringValues.CHANGESHIFT)); if (!shiftList.isEmpty()) { Integer shiftedNumber = this.productOutputMapper.getShiftedNumberByOutputIds(shiftList.stream().map(ProductOutput::getId).collect(Collectors.toList())); if (shiftedNumber > 0) { throw new RuntimeException("存在交班数据,交班产出已提交无法删除"); } } // 2.删除投入,先把投料剩余数量加上去再删除 List productInputList = productInputMapper.selectList(Wrappers.query().lambda().eq(ProductInput::getProductMainId, productMain.getId())); if (CollectionUtil.isNotEmpty(productInputList)) { // for (ProductInput productInput : productInputList) { // feedingUtils.update(productMain.getWorkstationId(), productInput, null, productInput.getInputQuantity()); // } productInputMapper.delete(Wrappers.query().lambda().eq(ProductInput::getProductMainId, productMain.getId())); } // 3.删除产出 productOutputMapper.deleteStaffOutByMainId(productMain.getId()); productOutputMapper.deleteArtificialInformationByMainId(productMain.getId()); //逻辑删除 productOutputMapper.delete(Wrappers.query().lambda().eq(ProductOutput::getProductMainId, productMain.getId())); // List productOutputList= productOutputMapper.selectList(Wrappers.query().lambda().eq(ProductOutput::getProductMainId, productMain.getId())); // if(!CollectionUtils.isEmpty(productOutputList)){ // productOutputList.stream().forEach(e->{ // e.setIsDeleted("1"); // productOutputMapper.updateById(e); // }); // } // 4.删除报工主表 baseMapper.deleteById(productMain.getId()); return true; } @Override public Long saveProductOutput(ProductMainDTO productMainDTO) { if (productMainDTO.getIsChangeShift()) { if (null != productMainDTO.getProductOutputList() && productMainDTO.getProductOutputList().size() > 1) { //解决按人员接班产出多条SN一样且为草稿状态的产出,提交时会对该两条产出的SN找到的交班记录相同,导致交班产出的投料被重复统计 throw new RuntimeException("接班生产 -> 若按人员报工 -> 则不支持指定多人"); } } ProductMain productMain = new ProductMain(); String state = "01pending"; if (productMainDTO.getId() == null) { // 1.自动创建报工主表 productMain.setOperationTaskId(productMainDTO.getOperationTaskId()); productMain.setWorkstationId(productMainDTO.getWorkstationId()); productMain.setProductNo(productMainNumberGenerator.generateNumberWithPrefix(ProductMain.DIGIT, ProductMain.PREFIX, ProductMain::getProductNo)); productMain.setState(ProductMainStateStringValues.DRAFT); baseMapper.insert(productMain); } else { productMain = baseMapper.selectById(productMainDTO.getId()); } if (ProductMainStateStringValues.SUBMITTED.equals(productMain.getState())) { throw new RuntimeException("报工记录已提交,无法修改"); } //产出之后如果工单的状态为等待,改成进行中 OperationTask operationTask = operationTaskMapper.selectById(productMainDTO.getOperationTaskId()); if (operationTask != null && state.equals(operationTask.getState())) { List ids = new ArrayList<>(); ids.add(productMainDTO.getOperationTaskId()); operationTaskService.changeState(ids, "START"); } //新增产出表和人员 addOutPutNew(productMainDTO.getProductOutputList(), productMain.getId(), productMainDTO.getWorkstationId(), productMainDTO.getIsChangeShift()); List outputList = productOutputMapper.selectList(Wrappers.lambdaQuery() .eq(ProductOutput::getProductMainId, productMain.getId())); List examinerList = examinerMapper.selectList(Wrappers.lambdaQuery() .eq(Examiner::getPartNo, partMapper.selectById(outputList.get(0).getPartId()).getPartNo())); if (CollectionUtil.isEmpty(examinerList)) { outputList.stream().forEach( a -> a.setOrigPartId(a.getPartId()) ); } else { outputList.stream().forEach( a -> { a.setOrigPartId(partMapper.selectOne(Wrappers.lambdaQuery().eq(Part::getPartNo, examinerList.get(0).getPartNo())).getId()); a.setPartId(partMapper.selectOne(Wrappers.lambdaQuery().eq(Part::getPartNo, examinerList.get(0).getPartNoAfter())).getId()); } ); } productOutputService.updateBatchById(outputList); //新增产出表和人员 return productMain.getId(); } @Override public Long batchSaveProductOutput(ProductMainDTO productMainDTO) { ProductMain productMain = new ProductMain(); String state = "01pending"; if (productMainDTO.getId() == null) { // 1.自动创建报工主表 productMain.setOperationTaskId(productMainDTO.getOperationTaskId()); productMain.setWorkstationId(productMainDTO.getWorkstationId()); productMain.setProductNo(productMainNumberGenerator.generateNumberWithPrefix(ProductMain.DIGIT, ProductMain.PREFIX, ProductMain::getProductNo)); productMain.setState(ProductMainStateStringValues.DRAFT); baseMapper.insert(productMain); } else { productMain = baseMapper.selectById(productMainDTO.getId()); } if (ProductMainStateStringValues.SUBMITTED.equals(productMain.getState())) { throw new RuntimeException("报工记录已提交,无法修改"); } //产出之后如果工单的状态为等待,改成进行中 OperationTask operationTask = operationTaskMapper.selectById(productMainDTO.getOperationTaskId()); if (operationTask != null && state.equals(operationTask.getState())) { List ids = new ArrayList<>(); ids.add(productMainDTO.getOperationTaskId()); operationTaskService.changeState(ids, "START"); } //新增产出表和人员 List productOutputDTOList = batchProductOutputDTOMake(productMainDTO.getProductOutputList()); addOutPutBatch(productOutputDTOList, productMain.getId(), productMain.getWorkstationId()); return productMain.getId(); } @Override public synchronized Boolean batchSaveProductMain(List productMainDTOList) { for (ProductMainDTO productMainDTO : productMainDTOList) { // 校验分段描述 checkSegmentDesc(productMainDTO.getProductOutputList().get(0).getSegmentDesc()); List mains = new ArrayList<>(); String state = "01pending"; String productNo = productMainNumberGenerator.generateNumberWithPrefix(ProductMain.DIGIT, ProductMain.PREFIX, ProductMain::getProductNo); int genNum = Integer.parseInt(productNo.substring(2)); for (int i = 0; i < productMainDTO.getDiscsNumber(); i++) { ProductMainDTO productMain = new ProductMainDTO(); List newProductOutputList = new ArrayList<>(); ProductOutputDTO newProductOutput = new ProductOutputDTO(); BeanUtils.copyProperties(productMainDTO.getProductOutputList().get(0), newProductOutput); if (CollectionUtil.isNotEmpty(productMainDTO.getOrderSnGenerateIdList())) { newProductOutput.setOrderSnGenerateIdList(productMainDTO.getOrderSnGenerateIdList()); } // 校验截止米标位数 checkEndMeterLength(newProductOutput.getEndMeterMark(), newProductOutput.getUnit()); newProductOutputList.add(newProductOutput); // 1.自动创建报工主表 productMain.setOperationTaskId(productMainDTO.getOperationTaskId()); productMain.setWorkstationId(productMainDTO.getWorkstationId()); productMain.setProductNo(ProductMain.PREFIX + String.format("%06d", genNum)); if (StringUtils.isNotBlank(productMainDTO.getMainRemark())) { boolean b = StringUtils.isNumeric(productMainDTO.getMainRemark()); Workstation workstation = workstationService.getById(productMainDTO.getWorkstationId()); if (b && workstation.getWorkCenter().equals("SP-07")) { for (ProductOutputDTO productOutputDTO : newProductOutputList) { int mainRemarkNum = Integer.parseInt(productMainDTO.getMainRemark()); productOutputDTO.setRemark(mainRemarkNum + i + ""); } } else { for (ProductOutputDTO productOutputDTO : newProductOutputList) { productOutputDTO.setRemark(productMainDTO.getMainRemark()); } } } /*if(productMainDTO.getMainRemark()==null){ long incr = redisUtils.incr("taskOperation" + productMainDTO.getOperationTaskId(), "00", 1); for (ProductOutputDTO productOutputDTO : newProductOutputList) { productOutputDTO.setRemark(incr + ""); } } else{ for (ProductOutputDTO productOutputDTO : newProductOutputList) { productOutputDTO.setRemark(productMainDTO.getMainRemark()); } }*/ productMain.setProductOutputList(newProductOutputList); productMain.setIsChangeShift(productMainDTO.getIsChangeShift()); productMain.setState(ProductMainStateStringValues.DRAFT); // baseMapper.insert(productMain); mains.add(productMain); genNum++; } int number = 500; if (CollectionUtil.isNotEmpty(mains)) { for (int j = 0; j <= mains.size() / number; j++) { if (CollectionUtil.isNotEmpty(mains.stream().skip(j * number).limit(number).collect(Collectors.toList()))) { this.saveBatch(mains.stream().skip(j * number).limit(number).collect(Collectors.toList())); } } } //产出之后如果工单的状态为等待,改成进行中 OperationTask operationTask = operationTaskMapper.selectById(productMainDTO.getOperationTaskId()); if (operationTask != null && state.equals(operationTask.getState())) { List ids = new ArrayList<>(); ids.add(productMainDTO.getOperationTaskId()); operationTaskService.changeState(ids, "START"); } // 批量新增产出和人员 addOutPutBatch(mains); for (ProductMainDTO main : mains) { List outputList = productOutputMapper.selectList(Wrappers.lambdaQuery() .eq(ProductOutput::getProductMainId, main.getId())); List examinerList = examinerMapper.selectList(Wrappers.lambdaQuery() .eq(Examiner::getPartNo, partMapper.selectById(outputList.get(0).getPartId()).getPartNo())); if (CollectionUtil.isEmpty(examinerList)) { outputList.stream().forEach( a -> a.setOrigPartId(a.getPartId()) ); } else { outputList.stream().forEach( a -> { a.setOrigPartId(partMapper.selectOne(Wrappers.lambdaQuery().eq(Part::getPartNo, examinerList.get(0).getPartNo())).getId()); a.setPartId(partMapper.selectOne(Wrappers.lambdaQuery().eq(Part::getPartNo, examinerList.get(0).getPartNoAfter())).getId()); } ); } productOutputService.updateBatchById(outputList); } // for (ProductMain main : mains) { // //新增产出表和人员 // addOutPutNew(productMainDTO.getProductOutputList(), main.getId(), productMainDTO.getWorkstationId(), productMainDTO.getIsChangeShift()); // } } return true; } private void checkEndMeterLength(BigDecimal endMeterMark, String unit) { String lengthLimit = remoteParamService.getByKey(OUTPUT_LENGTH_LIMIT, SecurityConstants.FROM_IN).getData(); String unitLimit = remoteParamService.getByKey(OUTPUT_UNIT_LIMIT, SecurityConstants.FROM_IN).getData(); if (StringUtils.isNotBlank(unitLimit)) { Boolean isUnit = unitLimit.equals(unit); if (StrUtil.isNotBlank(lengthLimit) && NumberUtils.isCreatable(lengthLimit) && isUnit) { int limit = Integer.parseInt(lengthLimit); BigDecimal checkEndMeterMark = endMeterMark.stripTrailingZeros(); if (checkEndMeterMark.precision() - checkEndMeterMark.scale() > limit) { throw new RuntimeException("填写的产量为" + endMeterMark + unit + ",不符合实际!"); } } } } private void addOutPutBatch(List mains) { // 获取工作站 Workstation workstation = workstationService.getById(mains.get(0).getWorkstationId()); // 获取工步 Step step = stepMapper.getFirstStep(mains.get(0).getOperationTaskId()); // 获取工序任务 OperationTask operationTask = operationTaskMapper.selectById(mains.get(0).getOperationTaskId()); // 是否交班 Boolean isShift = mains.get(0).getIsChangeShift(); // 工艺路线 MoRoutingOperation routingOperation = moRoutingOperationMapper.findByOperationTaskId(operationTask.getId()); List saveProductOutputList = new ArrayList<>(); //根据批次号进行循环 Set dutyRecordIds = new HashSet(); //检测申请零件 List applyPartList = new ArrayList<>(); //工单id Set operationTaskIds = new HashSet<>(); // 工步 List productStepList = new ArrayList<>(); Long staffId = null; Staff staff = staffMapper.getStaffByUserId(SecurityUtils.getUser().getId()); if (staff != null) { staffId = staff.getId(); } //每次新增人员都是使用同一个标识号 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String systemNo = formatter.format(LocalDateTime.now()); DateTimeFormatter snFormat = DateTimeFormatter.ofPattern("yyMMdd"); String snDate = snFormat.format(LocalDateTime.now()); /* //查询最新的SN号码 List snNos = operationTaskProduceMapper.getSnNumbers(snDate + "%"); //号码的处理 int num = 0; if (CollectionUtil.isNotEmpty(snNos)) { String soNo = snNos.get(0); num = Integer.parseInt(soNo.substring(6, soNo.length() - 1)); }*/ String genNumber = productOutputNumberGenerator.generateNumberWithPrefix(ProductOutput.DIGIT, ProductOutput.PREFIX, ProductOutput::getSystemNo); int genNum = Integer.parseInt(genNumber.substring(2)); Part part = partService.getById(mains.get(0).getProductOutputList().get(0).getPartId()); for (ProductMainDTO main : mains) { List lotbatchnoList = new ArrayList<>(); String manufatureAttr = StringUtils.isBlank(operationTask.getManufactureAttr()) ? "N" : operationTask.getManufactureAttr(); List productOutputDTOList = main.getProductOutputList(); for (int i = 0; i < productOutputDTOList.size(); i++) { ProductOutputDTO productOutputDTO = new ProductOutputDTO(); productOutputDTO.setSystemNo(ProductOutput.PREFIX + String.format("%06d", genNum)); productOutputDTO.setPartId(productOutputDTOList.get(i).getPartId()); productOutputDTO.setIsSnGenerateOutput(false); int num = Integer.parseInt(sequence.nextNo().substring(8)); String snno = snDate + String.format("%06d", num) + manufatureAttr; // 判断是否是段长生成的报工 if (CollectionUtil.isNotEmpty(productOutputDTOList.get(i).getOrderSnGenerateIdList())) { int check = manufacturingOrderSnGenerateService.count(Wrappers.lambdaQuery() .in(ManufacturingOrderSnGenerate::getId, productOutputDTOList.get(i).getOrderSnGenerateIdList()) .eq(ManufacturingOrderSnGenerate::getProduceStatus, true)); if (check > 0) { throw new RuntimeException("该批次号已经报工"); } manufacturingOrderSnGenerateService.updateProduceStatus(productOutputDTOList.get(i).getOrderSnGenerateIdList(), true, StringUtils.isNotBlank(productOutputDTOList.get(i).getOutBatchNo()) ? productOutputDTOList.get(i).getOutBatchNo() : snno); productOutputDTO.setIsSnGenerateOutput(true); } if (StringUtils.isBlank(productOutputDTOList.get(i).getOutBatchNo())) { //非交接新增 productOutputDTO.setOutBatchNo(snno); } else { productOutputDTO.setOutBatchNo(productOutputDTOList.get(i).getOutBatchNo()); if (isShift && CollectionUtil.isEmpty(productOutputDTOList.get(i).getOrderSnGenerateIdList())) { // 查询交班产出 ProductOutput shift = productOutputMapper.selectOne(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, productOutputDTO.getOutBatchNo()).orderByDesc(ProductOutput::getEndMeterMark).last("limit 1")); productOutputDTO.setShiftOutputId(shift.getId()); } } // 获取工步,如果存在工步,则执行跳线工步逻辑,清空产量信息 if (step != null) { //productOutputDTOList.get(i).setEndMeterMark(BigDecimal.ZERO); //productOutputDTOList.get(i).setStartMeterMark(BigDecimal.ZERO); productStepList.add(generateSteps(main.getId(), main.getOperationTaskId(), step, productOutputDTO)); } if (part.getLotTrackingIfs() != null && part.getLotTrackingIfs()) { productOutputDTO.setIfsBatchNo(StringUtils.isNotBlank(productOutputDTOList.get(i).getIfsBatchNo()) ? productOutputDTOList.get(i).getIfsBatchNo() : productOutputDTO.getOutBatchNo()); } else { productOutputDTO.setIfsBatchNo("*"); } productOutputDTO.setReelNumber(productOutputDTOList.get(i).getReelNumber()); productOutputDTO.setProductQty(productOutputDTOList.get(i).getEndMeterMark().subtract(productOutputDTOList.get(i).getStartMeterMark())); productOutputDTO.setProductMainId(main.getId()); productOutputDTO.setSortNo(num); productOutputDTO.setStartMeterMark(productOutputDTOList.get(i).getStartMeterMark()); productOutputDTO.setEndMeterMark(productOutputDTOList.get(i).getEndMeterMark()); productOutputDTO.setSegmentDesc(productOutputDTOList.get(i).getSegmentDesc()); productOutputDTO.setScrapQty(productOutputDTOList.get(i).getScrapQty() == null ? BigDecimal.ZERO : productOutputDTOList.get(i).getScrapQty()); productOutputDTO.setRemark(productOutputDTOList.get(i).getRemark()); productOutputDTO.setSproductQty(productOutputDTOList.get(i).getSproductQty()); productOutputDTO.setWorkstationId(workstation.getId()); productOutputDTO.setProductStaffIds(productOutputDTOList.get(i).getProductStaffIds()); productOutputDTO.setDutyRecordId(productOutputDTOList.get(i).getDutyRecordId()); productOutputDTO.setPartId(productOutputDTOList.get(i).getPartId()); productOutputDTO.setStatus(productOutputDTOList.get(i).getStatus()); productOutputDTO.setGrossWeight(productOutputDTOList.get(i).getGrossWeight()); productOutputDTO.setReelWeight(productOutputDTOList.get(i).getReelWeight()); // 盘具重量和毛重都不为空,则计算实际净重 if (productOutputDTOList.get(i).getReelWeight() != null && productOutputDTOList.get(i).getGrossWeight() != null) { productOutputDTO.setNetWeight(productOutputDTOList.get(i).getGrossWeight().subtract(productOutputDTOList.get(i).getReelWeight())); } productOutputDTO.setDiscToolMeasurement(productOutputDTOList.get(i).getDiscToolMeasurement()); saveProductOutputList.add(productOutputDTO); dutyRecordIds.add(productOutputDTOList.get(i).getDutyRecordId()); // 自动加投入 (如果有工步,自动投入在工步处理) //if (step == null) { // 跳线车间,报工单操作提前,不在最后一个工步的时候处理 autoAddInput(main.getOperationTaskId(), main.getWorkstationId(), main.getId(), productOutputDTO.getProductQty().add(productOutputDTO.getScrapQty() == null ? BigDecimal.ZERO : productOutputDTO.getScrapQty())); //} // 如果工单状态为等待或暂停,则改为开始 if (operationTask.getState().equals(OperationTaskStateStringValues.PENDING) || operationTask.getState().equals(OperationTaskStateStringValues.INTERRUPTED)) { operationTaskIds.add(main.getOperationTaskId()); } // 报工产量为0则生成首检 (去掉限制) if (routingOperation.getAutoInspection() != null && routingOperation.getAutoInspection()) { if (!isShift) { if (!lotbatchnoList.contains(snno)) { ApplyPartDTO partDTO = new ApplyPartDTO(); partDTO.setId(productOutputDTO.getId()); partDTO.setOutBatchNo(productOutputDTO.getOutBatchNo()); partDTO.setPartId(productOutputDTO.getPartId()); partDTO.setSystemNo(productOutputDTO.getSystemNo()); partDTO.setPartName(part.getPartName()); partDTO.setPartNo(part.getPartNo()); applyPartList.add(partDTO); lotbatchnoList.add(snno); } } } //num++; genNum++; } } int number = 500; if (CollectionUtil.isNotEmpty(saveProductOutputList)) { for (int j = 0; j <= saveProductOutputList.size() / number; j++) { if (CollectionUtil.isNotEmpty(saveProductOutputList.stream().skip(j * number).limit(number).collect(Collectors.toList()))) { productOutputMapper.batchInsert(saveProductOutputList.stream().skip(j * number).limit(number).collect(Collectors.toList())); } } } //修改对应的人员数据 buildOutStaffBatch(saveProductOutputList, systemNo); // buildOutStaff(productOutputDTOList.get(i).getProductStaffIds(), productOutputDTO.getId(), productOutputDTOList.get(i).getProductQty(), productOutputDTOList.get(i).getStatus(), systemNo, productOutputDTOList.get(i).getDutyRecordId()); //根据人员数据自动生成零件对应的人工记录 autoBuildArtificialInformationBatch(saveProductOutputList); // autoBuildArtificialInformation(productOutputDTOList.get(i).getProductStaffIds(), productOutputDTO.getId(), productOutputDTOList.get(i).getProductQty(), productOutputDTOList.get(i).getDutyRecordId(), productOutputDTOList.get(i).getPartId(), productMain.getWorkstationId(), productOutputDTO.getOutBatchNo()); // 更新班次产量 refreshDutyRecord(dutyRecordIds); // 生成首检 if (!applyPartList.isEmpty()) { //ApplyDTO applyDTO = new ApplyDTO(); //applyDTO.setApplyPartList(applyPartList); //applyDTO.setApplyType(Apply.FIRST_APPLY); //ThreadUtil.execAsync(() -> applyService.saveDto(applyDTO)); //工作台产出记录创建时批量生成一个首检申请单改为单独申请首检申请单【2022-09-20】 for (int i = 0; i < applyPartList.size(); i++) { ApplyDTO applyDTO = new ApplyDTO(); List applyPartDTOList = new ArrayList<>(); applyPartDTOList.add(applyPartList.get(i)); applyDTO.setApplyPartList(applyPartDTOList); applyDTO.setApplyType(Apply.FIRST_APPLY); applyDTO.setRemark("自动报检:" + workstation.getName());//新增首检的备注【2022-09-22】 applyService.saveDto(applyDTO); } } // 将工单状态改为进行中 if (!operationTaskIds.isEmpty()) { operationTaskService.changeState(new ArrayList<>(operationTaskIds), "START"); } // 保存工步 if (!productStepList.isEmpty()) { Long staffId1 = staffId; ThreadUtil.execute(() -> addProductOutStep(productStepList, staffId1)); } } private void autoBuildArtificialInformationBatch(List saveProductOutputList) { List saveList = new ArrayList<>(); for (ProductOutputDTO productOutputDTO : saveProductOutputList) { // 1.根据零件/工作站查询对应的人工类型 HandymanType handymanType = handymanTypeMapper.selectByWorkstationIdAndPartId(productOutputDTO.getWorkstationId(), productOutputDTO.getPartId()); if (handymanType != null) { // 2.再生成对应的人工记录 if (CollectionUtil.isNotEmpty(productOutputDTO.getProductStaffIds())) { List ids = new ArrayList(); for (Long staffId : productOutputDTO.getProductStaffIds()) { // 根据人员编号/班次id查出对应的上班人员id PersonBoard personBoard = personBoardMapper.selectByDutyRecordIdAndStaffId(productOutputDTO.getDutyRecordId(), staffId); ArtificialInformation artificialInformation = new ArtificialInformation(); artificialInformation.setOutputId(productOutputDTO.getId()); artificialInformation.setPersonOutput(productOutputDTO.getProductQty()); artificialInformation.setDutyRecordId(productOutputDTO.getDutyRecordId()); artificialInformation.setHandymanTypeId(handymanType.getId()); artificialInformation.setRemark(productOutputDTO.getRemark()); if (personBoard != null) { artificialInformation.setProductionPersonId(personBoard.getId()); } saveList.add(artificialInformation); ids.add(artificialInformation.getId()); } } } } int number = 500; if (CollectionUtil.isNotEmpty(saveList)) { for (int j = 0; j <= saveList.size() / number; j++) { if (CollectionUtil.isNotEmpty(saveList.stream().skip(j * number).limit(number).collect(Collectors.toList()))) { artificialInformationMapper.batchInsert(saveList.stream().skip(j * number).limit(number).collect(Collectors.toList())); } } } } private void buildOutStaffBatch(List saveProductOutputList, String systemNo) { List saveList = new ArrayList<>(); for (ProductOutputDTO productOutputDTO : saveProductOutputList) { if (CollectionUtil.isNotEmpty(productOutputDTO.getProductStaffIds())) { List staffList = staffMapper.selectListAll(); for (Long staff : productOutputDTO.getProductStaffIds()) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); ProductOutputStaff outputStaff = new ProductOutputStaff(); staffList.forEach(a -> { if (a.getId().equals(staff)) { outputStaff.setStaffNo(a.getStaffNo()); } }); outputStaff.setStaffId(staff); outputStaff.setProductOutId(productOutputDTO.getId()); outputStaff.setSystemNo(systemNo); outputStaff.setDutyRecordId(productOutputDTO.getDutyRecordId()); outputStaff.setDate(formatter.format(LocalDateTime.now())); outputStaff.setQuantity(productOutputDTO.getProductQty()); outputStaff.setArtificialType(productOutputDTO.getStatus()); saveList.add(outputStaff); } } } int number = 500; if (CollectionUtil.isNotEmpty(saveList)) { for (int j = 0; j <= saveList.size() / number; j++) { if (CollectionUtil.isNotEmpty(saveList.stream().skip(j * number).limit(number).collect(Collectors.toList()))) { productOutputStaffMapper.batchInsert(saveList.stream().skip(j * number).limit(number).collect(Collectors.toList())); } } } } private ProductStep generateSteps(Long productMainId, Long operationTaskId, Step step, ProductOutputDTO productOutput) { //报工的工步 ProductStep productStep = new ProductStep(); productStep.setStepId(step.getId()); productStep.setOperationTaskId(operationTaskId); productStep.setNumber(BigDecimal.ZERO); productStep.setProductMainId(productMainId); productStep.setStepBatchNo(productOutput.getIfsBatchNo()); productStep.setSystemNo(productOutput.getOutBatchNo()); return productStep; } @Override public Boolean batchUpdateProductMain(List productMainDTOList) { for (ProductMainDTO productMainDTO : productMainDTOList) { // 校验分段描述 checkSegmentDesc(productMainDTO.getProductOutputList().get(0).getSegmentDesc()); // 校验截止米标位数 checkEndMeterLength(productMainDTO.getProductOutputList().get(0).getEndMeterMark(), productMainDTO.getProductOutputList().get(0).getUnit()); } for (ProductMainDTO productMainDTO : productMainDTOList) { List productOutputs = productOutputMapper.selectList(Wrappers.lambdaQuery().eq(ProductOutput::getProductMainId, productMainDTO.getId())); for (ProductOutput productOutput : productOutputs) { ProductOutputDTO productOutputDTO = productMainDTO.getProductOutputList().get(0); ProductOutput productOutputOriginal = productOutputMapper.selectById(productOutput.getId()); BigDecimal oldProductQty = productOutputOriginal.getProductQty(); BigDecimal oldScrapQty = productOutputOriginal.getScrapQty(); ProductMain productMain = baseMapper.selectById(productOutputOriginal.getProductMainId()); if (ProductMainStateStringValues.SUBMITTED.equals(productMain.getState())) { throw new RuntimeException("报工记录已提交,无法修改"); } if (StringUtils.equals(ProductMainStateStringValues.PROCESSING, productMain.getState())) { throw new RuntimeException("报工记录处理中,无法修改"); } productOutputOriginal.setReelNumber(productOutputDTO.getReelNumber()); productOutputOriginal.setStartMeterMark(productOutputDTO.getStartMeterMark()); productOutputOriginal.setEndMeterMark(productOutputDTO.getEndMeterMark()); productOutputOriginal.setProductQty(productOutputDTO.getEndMeterMark().subtract(productOutputDTO.getStartMeterMark())); productOutputOriginal.setOutBatchNo(productOutputDTO.getOutBatchNo()); productOutputOriginal.setIfsBatchNo(productOutputDTO.getIfsBatchNo()); productOutputOriginal.setSegmentDesc(productOutputDTO.getSegmentDesc()); productOutputOriginal.setScrapQty(productOutputDTO.getScrapQty()); productOutputOriginal.setRemark(productOutputDTO.getRemark()); productOutputOriginal.setGrossWeight(productOutputDTO.getGrossWeight()); productOutputOriginal.setReelWeight(productOutputDTO.getReelWeight()); if (productOutputOriginal.getGrossWeight() != null && productOutputOriginal.getReelWeight() != null) { productOutputOriginal.setNetWeight(productOutputOriginal.getGrossWeight().subtract(productOutputOriginal.getReelWeight())); } productOutputMapper.updateById(productOutputOriginal); UpdateWrapper updateWrapper = new UpdateWrapper(); updateWrapper.lambda().eq(ProductOutputStaff::getProductOutId, productOutputOriginal.getId()).set(ProductOutputStaff::getQuantity, productOutputOriginal.getProductQty()); productOutputStaffMapper.update(null, updateWrapper); //修改投料的数量(投料计算:产出数量+报废数量) BigDecimal incrementQty = oldProductQty.add(oldScrapQty).subtract(productOutputOriginal.getProductQty()).subtract(productOutputOriginal.getScrapQty() == null ? BigDecimal.ZERO : productOutputOriginal.getScrapQty()); if (incrementQty.compareTo(BigDecimal.ZERO) == 1) { // 根据终值去计算投入,不再根据增量去删 autoDeleteInputV2(Collections.singletonList(productMain.getId()), TransactionType.OUTPUT_UPDATE.getValue()); autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), productOutputOriginal.getProductQty().add(productOutputOriginal.getScrapQty() == null ? BigDecimal.ZERO : productOutputOriginal.getScrapQty())); } else if (incrementQty.compareTo(BigDecimal.ZERO) == -1) { // 自动加投入 autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), incrementQty.negate()); } // 更新班次产量 List productOutputStaffList = productOutputStaffMapper.selectList(Wrappers.lambdaQuery().in(ProductOutputStaff::getProductOutId, productOutput.getId())); Set dutyRecordIds = productOutputStaffList.stream().map(ProductOutputStaff::getDutyRecordId).collect(Collectors.toSet()); refreshDutyRecord(dutyRecordIds); //dutyRecordMapper.refreshDutyOutputById(productOutputDTO.getDutyRecordId()); } } return true; } public void checkSegmentDesc(String segmentDesc) { if (StringUtils.isNotBlank(segmentDesc)) { String[] split = segmentDesc.split("\\+"); if (split.length > 1) { for (String desc : split) { if (!NumberUtils.isCreatable(desc)) { throw new RuntimeException("分段描述只能用数字分段"); } } } else { throw new RuntimeException("分段描述格式不正确"); } } } private List batchProductOutputDTOMake(List productOutputDTOS) { List productOutputDTOList = new LinkedList<>(); for (ProductOutputDTO productOutputDTO : productOutputDTOS) { for (int i = 0; i < productOutputDTO.getDisNumber(); i++) { ProductOutputDTO outputDTO = new ProductOutputDTO(); outputDTO.setWorkstationId(productOutputDTO.getWorkstationId()); outputDTO.setOperationTaskId(productOutputDTO.getOperationTaskId()); outputDTO.setPartId(productOutputDTO.getPartId()); outputDTO.setStartMeterMark(BigDecimal.ZERO); outputDTO.setEndMeterMark(productOutputDTO.getProductQty()); outputDTO.setProductQty(productOutputDTO.getProductQty()); outputDTO.setProductStaffs(productOutputDTO.getProductStaffs()); outputDTO.setProductStaffIds(productOutputDTO.getProductStaffIds()); outputDTO.setDutyRecordId(productOutputDTO.getDutyRecordId()); outputDTO.setStatus(productOutputDTO.getStatus()); outputDTO.setProductMainId(productOutputDTO.getProductMainId()); outputDTO.setRemark(productOutputDTO.getRemark()); outputDTO.setIfsBatchNo(productOutputDTO.getIfsBatchNo()); outputDTO.setReelNumber(productOutputDTO.getReelNumber()); outputDTO.setScrapQty(productOutputDTO.getScrapQty()); outputDTO.setSegmentDesc(productOutputDTO.getSegmentDesc()); productOutputDTOList.add(outputDTO); } } return productOutputDTOList; } private void addOutPut(List productOutputDTOList, Long id, Long workstationId) { //根据产出批号进行分组 Map> productOutputList = productOutputDTOList.stream().collect(Collectors.groupingBy(ProductOutput::getOutBatchNo)); //每次新增人员都是使用同一个标识号 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String systemNo = formatter.format(LocalDateTime.now()); //根据批次号进行循环 Set dutyRecordIds = new HashSet(); for (String key : productOutputList.keySet()) { ProductOutputDTO productOutputDTO = new ProductOutputDTO(); //查询是否存在相同批次的产出 ProductOutput dbOutput = productOutputMapper.selectOne(Wrappers.lambdaQuery() .eq(ProductOutput::getProductMainId, id).eq(ProductOutput::getOutBatchNo, key)); //获取当前key下的产出数据 List productOutput = productOutputList.get(key); if (dbOutput != null) { //如果存在相同批次的产出 BigDecimal productQty = dbOutput.getProductQty(); for (ProductOutputDTO newProductOutput : productOutput) { productQty = productQty.add(newProductOutput.getProductQty()); productOutputDTO.setPartId(dbOutput.getPartId()); productOutputDTO.setOutBatchNo(dbOutput.getOutBatchNo()); productOutputDTO.setProductMainId(dbOutput.getProductMainId()); productOutputDTO.setSystemNo(dbOutput.getSystemNo()); productOutputDTO.setId(dbOutput.getId()); dutyRecordIds.add(newProductOutput.getDutyRecordId()); //修改对应的人员数据 buildOutStaff(newProductOutput.getProductStaffIds(), dbOutput.getId(), newProductOutput.getProductQty(), newProductOutput.getStatus(), systemNo, newProductOutput.getDutyRecordId()); //根据人员数据自动生成零件对应的人工记录 autoBuildArtificialInformation(newProductOutput.getProductStaffIds(), productOutputDTO.getId(), newProductOutput.getProductQty(), newProductOutput.getDutyRecordId(), newProductOutput.getPartId(), workstationId, key); } productOutputDTO.setProductQty(productQty); productOutputMapper.updateById(productOutputDTO); } else { BigDecimal productQty = BigDecimal.ZERO; for (ProductOutputDTO newProductOutput : productOutput) { productOutputDTO.setSystemNo(productOutputNumberGenerator.generateNumberWithPrefix(ProductOutput.DIGIT, ProductOutput.PREFIX, ProductOutput::getSystemNo)); productQty = productQty.add(newProductOutput.getProductQty()); productOutputDTO.setPartId(newProductOutput.getPartId()); productOutputDTO.setOutBatchNo(newProductOutput.getOutBatchNo()); } productOutputDTO.setProductQty(productQty); productOutputDTO.setProductMainId(id); productOutputMapper.insert(productOutputDTO); for (ProductOutputDTO newProductOutput : productOutput) { dutyRecordIds.add(newProductOutput.getDutyRecordId()); //修改对应的人员数据 buildOutStaff(newProductOutput.getProductStaffIds(), productOutputDTO.getId(), newProductOutput.getProductQty(), newProductOutput.getStatus(), systemNo, newProductOutput.getDutyRecordId()); //根据人员数据自动生成零件对应的人工记录 autoBuildArtificialInformation(newProductOutput.getProductStaffIds(), productOutputDTO.getId(), newProductOutput.getProductQty(), newProductOutput.getDutyRecordId(), newProductOutput.getPartId(), workstationId, key); } } ProductMain productMain = baseMapper.selectById(productOutputDTO.getProductMainId()); if (dbOutput != null) { BigDecimal incrementQty = dbOutput.getProductQty().subtract(productOutputDTO.getProductQty()); if (incrementQty.compareTo(BigDecimal.ZERO) == 1) { // 自动删投入 autoDeleteInput(productOutputDTO.getProductMainId(), incrementQty); } else if (incrementQty.compareTo(BigDecimal.ZERO) == -1) { // 自动加投入 autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), incrementQty.negate()); } } else { autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), productOutputDTO.getProductQty()); } } // 更新班次产量 refreshDutyRecord(dutyRecordIds); } private synchronized void addOutPutBatch(List productOutputDTOList, Long id, Long workstationId) { DateTimeFormatter snFormat = DateTimeFormatter.ofPattern("yyMMdd"); String snDate = snFormat.format(LocalDateTime.now()); Workstation workstation = workstationService.getById(workstationId); // SN码= 2位年 + 2位月 + 2位日 + 六位流水号 + 工单制造类型 String sn = snDate; //每次新增人员都是使用同一个标识号 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); // String systemNo = formatter.format(LocalDateTime.now()); //根据批次号进行循环 Set dutyRecordIds = new HashSet(); //检测申请零件 List applyPartList = new ArrayList<>(); //工单id Set operationTaskIds = new HashSet<>(); List snNos = operationTaskProduceMapper.getSnNumbers(snDate + "%"); int num = 0; if (CollectionUtil.isNotEmpty(snNos)) { String snNo = snNos.get(0); num = Integer.parseInt(snNo.substring(6, snNo.length() - 1)); } // 校验分段描述 for (ProductOutputDTO productOutputDTO : productOutputDTOList) { checkSegmentDesc(productOutputDTO.getSegmentDesc()); } ProductMain productMain = baseMapper.selectById(id); OperationTask operationTask = operationTaskMapper.selectById(productMain.getOperationTaskId()); String manufatureAttr = StringUtils.isBlank(operationTask.getManufactureAttr()) ? "N" : operationTask.getManufactureAttr(); for (int i = 0; i < productOutputDTOList.size(); i++) { ProductOutputDTO productOutputDTO = new ProductOutputDTO(); productOutputDTO.setSystemNo(productOutputNumberGenerator.generateNumberWithPrefix(ProductOutput.DIGIT, ProductOutput.PREFIX, ProductOutput::getSystemNo)); productOutputDTO.setPartId(productOutputDTOList.get(i).getPartId()); //SN号码 productOutputDTO.setOutBatchNo(sn + String.format("%06d", num + 1) + manufatureAttr); //数量 productOutputDTO.setProductQty(productOutputDTOList.get(i).getProductQty()); //载具编号 productOutputDTO.setReelNumber(productOutputDTOList.get(i).getReelNumber()); //主表id productOutputDTO.setProductMainId(id); //序号 productOutputDTO.setSortNo(num + 1); //开始计米 productOutputDTO.setStartMeterMark(productOutputDTOList.get(i).getStartMeterMark()); //结束计米 productOutputDTO.setEndMeterMark(productOutputDTOList.get(i).getEndMeterMark()); //ifs批次号 productOutputDTO.setIfsBatchNo(StringUtils.isNotBlank(productOutputDTOList.get(i).getIfsBatchNo()) ? productOutputDTOList.get(i).getIfsBatchNo() : productOutputDTO.getOutBatchNo()); //报废数量 productOutputDTO.setScrapQty(productOutputDTOList.get(i).getScrapQty()); //分段描述 productOutputDTO.setSegmentDesc(productOutputDTOList.get(i).getSegmentDesc()); //备注 productOutputDTO.setRemark(productOutputDTOList.get(i).getRemark()); productOutputMapper.insert(productOutputDTO); dutyRecordIds.add(productOutputDTOList.get(i).getDutyRecordId()); //修改对应的人员数据 buildOutStaff(productOutputDTOList.get(i).getProductStaffIds(), productOutputDTO.getId(), productOutputDTOList.get(i).getProductQty(), productOutputDTOList.get(i).getStatus(), systemNo, productOutputDTOList.get(i).getDutyRecordId()); //根据人员数据自动生成零件对应的人工记录 autoBuildArtificialInformation(productOutputDTOList.get(i).getProductStaffIds(), productOutputDTO.getId(), productOutputDTOList.get(i).getProductQty(), productOutputDTOList.get(i).getDutyRecordId(), productOutputDTOList.get(i).getPartId(), workstationId, productOutputDTO.getOutBatchNo()); // 自动加投入 autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), productOutputDTO.getProductQty().add(productOutputDTO.getScrapQty() == null ? BigDecimal.ZERO : productOutputDTO.getScrapQty())); // 如果工单状态为等待或暂停,则改为开始 if (operationTask.getState().equals(OperationTaskStateStringValues.PENDING) || operationTask.getState().equals(OperationTaskStateStringValues.INTERRUPTED)) { operationTaskIds.add(productMain.getOperationTaskId()); } ApplyPartDTO partDTO = new ApplyPartDTO(); partDTO.setId(productOutputDTO.getId()); partDTO.setOutBatchNo(productOutputDTO.getOutBatchNo()); partDTO.setPartId(productOutputDTO.getPartId()); partDTO.setSystemNo(productOutputDTO.getSystemNo()); Part part = partService.getById(partDTO.getPartId()); partDTO.setPartName(part.getPartName()); partDTO.setPartNo(part.getPartNo()); applyPartList.add(partDTO); num += 1; } // 更新班次产量 refreshDutyRecord(dutyRecordIds); // 生成首检 if (!applyPartList.isEmpty()) { //ApplyDTO applyDTO = new ApplyDTO(); //applyDTO.setApplyPartList(applyPartList); //applyDTO.setApplyType(Apply.FIRST_APPLY); //applyService.saveDto(applyDTO); //工作台产出记录创建时批量生成一个首检申请单改为单独申请首检申请单【2022-09-20】 for (int i = 0; i < applyPartList.size(); i++) { ApplyDTO applyDTO = new ApplyDTO(); List applyPartDTOList = new ArrayList<>(); applyPartDTOList.add(applyPartList.get(i)); applyDTO.setApplyPartList(applyPartDTOList); applyDTO.setApplyType(Apply.FIRST_APPLY); applyDTO.setRemark("自动报检:" + workstation.getName());//新增首检的备注【2022-09-22】 applyService.saveDto(applyDTO); } } // 将工单状态改为进行中 if (!operationTaskIds.isEmpty()) { operationTaskService.changeState(new ArrayList<>(operationTaskIds), "START"); } } private synchronized void addOutPutNew(List productOutputDTOList, Long id, Long workstationId, Boolean isShift) { DateTimeFormatter snFormat = DateTimeFormatter.ofPattern("yyMMdd"); String snDate = snFormat.format(LocalDateTime.now()); Workstation workstation = workstationService.getById(workstationId); // SN码=2位年+月+机台号+日+俩位数流水 String sn = snDate.substring(0, 4) + workstation.getWorkstationNo() + snDate.substring(4); //每次新增人员都是使用同一个标识号 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); // String systemNo = formatter.format(LocalDateTime.now()); //根据批次号进行循环 Set dutyRecordIds = new HashSet(); //检测申请零件 List applyPartList = new ArrayList<>(); //工单id Set operationTaskIds = new HashSet<>(); /* //查询最新的SN号码 List snNos = operationTaskProduceMapper.getSnNumbers(snDate + "%"); //号码的处理 int num = 0; if (CollectionUtil.isNotEmpty(snNos)) { String soNo = snNos.get(0); num = Integer.parseInt(soNo.substring(6, soNo.length() - 1)); }*/ List lotbatchnoList = new ArrayList<>(); ProductMain productMain = baseMapper.selectById(id); // 获取工步 Step step = stepMapper.getFirstStep(productMain.getOperationTaskId()); List productStepList = new ArrayList<>(); Long staffId = null; Staff staff = staffMapper.getStaffByUserId(SecurityUtils.getUser().getId()); if (staff != null) { staffId = staff.getId(); } OperationTask operationTask = operationTaskMapper.selectById(productMain.getOperationTaskId()); String manufatureAttr = StringUtils.isBlank(operationTask.getManufactureAttr()) ? "N" : operationTask.getManufactureAttr(); for (int i = 0; i < productOutputDTOList.size(); i++) { // 校验截止米标位数 checkEndMeterLength(productOutputDTOList.get(i).getEndMeterMark(), productOutputDTOList.get(i).getUnit()); ProductOutputDTO productOutputDTO = new ProductOutputDTO(); productOutputDTO.setSystemNo(productOutputNumberGenerator.generateNumberWithPrefix(ProductOutput.DIGIT, ProductOutput.PREFIX, ProductOutput::getSystemNo)); productOutputDTO.setPartId(productOutputDTOList.get(i).getPartId()); int num = Integer.parseInt(sequence.nextNo().substring(8)); String snno = snDate + String.format("%06d", num) + manufatureAttr; if (StringUtils.isBlank(productOutputDTOList.get(i).getOutBatchNo())) { //非交接新增 productOutputDTO.setOutBatchNo(snno); } else { productOutputDTO.setOutBatchNo(productOutputDTOList.get(i).getOutBatchNo()); if (isShift) { // 查询交班产出 ProductOutput shift = productOutputMapper.selectOne(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, productOutputDTO.getOutBatchNo()).orderByDesc(ProductOutput::getEndMeterMark).last("limit 1")); productOutputDTO.setShiftOutputId(shift.getId()); } } // 获取工步,如果存在工步,则执行跳线工步逻辑,清空产量信息 if (step != null) { productOutputDTOList.get(i).setEndMeterMark(BigDecimal.ZERO); productOutputDTOList.get(i).setStartMeterMark(BigDecimal.ZERO); productStepList.add(generateSteps(productMain.getId(), productMain.getOperationTaskId(), step, productOutputDTO)); } productOutputDTO.setIfsBatchNo(StringUtils.isNotBlank(productOutputDTOList.get(i).getIfsBatchNo()) ? productOutputDTOList.get(i).getIfsBatchNo() : productOutputDTO.getOutBatchNo()); productOutputDTO.setReelNumber(productOutputDTOList.get(i).getReelNumber()); productOutputDTO.setProductQty(productOutputDTOList.get(i).getEndMeterMark().subtract(productOutputDTOList.get(i).getStartMeterMark())); productOutputDTO.setProductMainId(id); productOutputDTO.setSortNo(num); productOutputDTO.setStartMeterMark(productOutputDTOList.get(i).getStartMeterMark()); productOutputDTO.setEndMeterMark(productOutputDTOList.get(i).getEndMeterMark()); productOutputDTO.setSegmentDesc(productOutputDTOList.get(i).getSegmentDesc()); productOutputDTO.setScrapQty(productOutputDTOList.get(i).getScrapQty()); productOutputDTO.setRemark(productOutputDTOList.get(i).getRemark()); productOutputDTO.setSproductQty(productOutputDTOList.get(i).getSproductQty()); productOutputMapper.insert(productOutputDTO); dutyRecordIds.add(productOutputDTOList.get(i).getDutyRecordId()); //修改对应的人员数据 buildOutStaff(productOutputDTOList.get(i).getProductStaffIds(), productOutputDTO.getId(), productOutputDTOList.get(i).getProductQty(), productOutputDTOList.get(i).getStatus(), systemNo, productOutputDTOList.get(i).getDutyRecordId()); //根据人员数据自动生成零件对应的人工记录 autoBuildArtificialInformation(productOutputDTOList.get(i).getProductStaffIds(), productOutputDTO.getId(), productOutputDTOList.get(i).getProductQty(), productOutputDTOList.get(i).getDutyRecordId(), productOutputDTOList.get(i).getPartId(), productMain.getWorkstationId(), productOutputDTO.getOutBatchNo()); // 自动加投入 autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), productOutputDTO.getProductQty().add(productOutputDTO.getScrapQty() == null ? BigDecimal.ZERO : productOutputDTO.getScrapQty())); // 如果工单状态为等待或暂停,则改为开始 if (operationTask.getState().equals(OperationTaskStateStringValues.PENDING) || operationTask.getState().equals(OperationTaskStateStringValues.INTERRUPTED)) { operationTaskIds.add(productMain.getOperationTaskId()); } MoRoutingOperation routingOperation = moRoutingOperationMapper.findByProductMainId(productMain.getId()); // 报工产量为0则生成首检 (去掉限制) if (routingOperation.getAutoInspection() != null && routingOperation.getAutoInspection()) { if (!isShift) { if (!lotbatchnoList.contains(snno)) { ApplyPartDTO partDTO = new ApplyPartDTO(); partDTO.setId(productOutputDTO.getId()); partDTO.setOutBatchNo(productOutputDTO.getOutBatchNo()); partDTO.setPartId(productOutputDTO.getPartId()); partDTO.setSystemNo(productOutputDTO.getSystemNo()); Part part = partService.getById(partDTO.getPartId()); partDTO.setPartName(part.getPartName()); partDTO.setPartNo(part.getPartNo()); applyPartList.add(partDTO); lotbatchnoList.add(snno); } } } //num++; } // 更新班次产量 refreshDutyRecord(dutyRecordIds); // 生成首检 if (!applyPartList.isEmpty()) { //ApplyDTO applyDTO = new ApplyDTO(); //applyDTO.setApplyPartList(applyPartList); //applyDTO.setApplyType(Apply.FIRST_APPLY); //applyService.saveDto(applyDTO); //工作台产出记录创建时批量生成一个首检申请单改为单独申请首检申请单【2022-09-20】 for (int i = 0; i < applyPartList.size(); i++) { ApplyDTO applyDTO = new ApplyDTO(); List applyPartDTOList = new ArrayList<>(); applyPartDTOList.add(applyPartList.get(i)); applyDTO.setApplyPartList(applyPartDTOList); applyDTO.setApplyType(Apply.FIRST_APPLY); applyDTO.setRemark("自动报检:" + workstation.getName());//新增首检的备注【2022-09-22】 applyService.saveDto(applyDTO); } } // 将工单状态改为进行中 if (!operationTaskIds.isEmpty()) { operationTaskService.changeState(new ArrayList<>(operationTaskIds), "START"); } // 保存工步 if (!productStepList.isEmpty()) { Long staffId1 = staffId; ThreadUtil.execute(() -> addProductOutStep(productStepList, staffId1)); } } private void addProductOutStep(List productStepList, Long id) { int number = 500; if (CollectionUtil.isNotEmpty(productStepList)) { for (int j = 0; j <= productStepList.size() / number; j++) { if (CollectionUtil.isNotEmpty(productStepList.stream().skip(j * number).limit(number).collect(Collectors.toList()))) { productStepMapper.addProductOutStep(productStepList.stream().skip(j * number).limit(number).collect(Collectors.toList())); productStepStaffMapper.addProductOutStepStaff(productStepList.stream().skip(j * number).limit(number).collect(Collectors.toList()), id); } } } } /** * 报工到人 * * @param staffIds * @param productOutId */ private void buildOutStaff(List staffIds, Long productOutId, BigDecimal productQty, Boolean status, String systemNo, Long id) { if (CollectionUtil.isNotEmpty(staffIds)) { List staffList = staffMapper.selectListAll(); for (Long staff : staffIds) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); ProductOutputStaff outputStaff = new ProductOutputStaff(); staffList.forEach(a -> { if (a.getId().equals(staff)) { outputStaff.setStaffNo(a.getStaffNo()); } }); outputStaff.setStaffId(staff); outputStaff.setProductOutId(productOutId); outputStaff.setSystemNo(systemNo); outputStaff.setDutyRecordId(id); outputStaff.setDate(formatter.format(LocalDateTime.now())); outputStaff.setQuantity(productQty); outputStaff.setArtificialType(status); productOutputStaffMapper.insert(outputStaff); } } } /** * 根据人员数据自动生成零件对应的人工记录 */ private void autoBuildArtificialInformation(List staffIds, Long productOutId, BigDecimal productQty, Long dutyRecordId, Long partId, Long workstationId, String remark) { // 1.根据零件/工作站查询对应的人工类型 HandymanType handymanType = handymanTypeMapper.selectByWorkstationIdAndPartId(workstationId, partId); if (handymanType != null) { // 2.再生成对应的人工记录 if (CollectionUtil.isNotEmpty(staffIds)) { List ids = new ArrayList(); for (Long staffId : staffIds) { // 根据人员编号/班次id查出对应的上班人员id PersonBoard personBoard = personBoardMapper.selectByDutyRecordIdAndStaffId(dutyRecordId, staffId); ArtificialInformation artificialInformation = new ArtificialInformation(); artificialInformation.setOutputId(productOutId); artificialInformation.setPersonOutput(productQty); artificialInformation.setDutyRecordId(dutyRecordId); artificialInformation.setHandymanTypeId(handymanType.getId()); artificialInformation.setRemark(remark); if (personBoard != null) { artificialInformation.setProductionPersonId(personBoard.getId()); } artificialInformationMapper.insert(artificialInformation); ids.add(artificialInformation.getId()); } } } } /** * 自动添加对应数量的投入 */ public void autoAddInput1(Long operationTaskId, Long workstationId, Long productMainId, BigDecimal productQty) { // 3.1.根据工单查询投入产出比 List operationTaskMaterialList = operationTaskMaterialMapper.selectList(Wrappers.query().lambda(). eq(OperationTaskMaterial::getOperationTaskId, operationTaskId)); if (CollectionUtil.isNotEmpty(operationTaskMaterialList)) { // 3.2 根据投入比去查询对应的投料数量 FeedingDTO param = new FeedingDTO(); param.setWorkstationId(workstationId); for (OperationTaskMaterial operationTaskMaterial : operationTaskMaterialList) { param.setPartId(operationTaskMaterial.getPartId()); // 根据零件id和工作站id 查询投料数据 List feedingList = feedingMapper.getFeedingByParam(QueryWrapperUtil.gen(param)); // 投入总数量=投入比*产出数量 BigDecimal summary = operationTaskMaterial.getQpa().multiply(productQty); if (CollectionUtil.isNotEmpty(feedingList)) { for (FeedingDTO feedingDTO : feedingList) { BigDecimal feedingCost; ProductInput productInput = productInputMapper.selectOne(Wrappers.lambdaQuery() .eq(ProductInput::getProductMainId, productMainId).eq(ProductInput::getPartId, feedingDTO.getPartId()) .eq(ProductInput::getPartBatchNo, feedingDTO.getPartBatchNo()).eq(ProductInput::getSystemNo, feedingDTO.getSystemNo()) .eq(ProductInput::getStockId, feedingDTO.getStockId())); if (feedingDTO.getResidualQuantity().compareTo(summary) == -1) { feedingCost = feedingDTO.getResidualQuantity(); summary = summary.subtract(feedingDTO.getResidualQuantity()); } else { feedingCost = summary; summary = BigDecimal.ZERO; } // addOrUpdateProductInput(productInput, feedingDTO, feedingCost, productMainId); // 3.4 减去对应投料数量 feedingUtils.updateById(feedingDTO.getId(), null, feedingCost.negate()); if (summary.compareTo(BigDecimal.ZERO) == 0) { break; } } } } } } /** * 自动添加对应数量的投入 */ public void autoAddInput(Long operationTaskId, Long workstationId, Long productMainId, BigDecimal productQty) { String taskMoNo = operationTaskMapper.getTaskMoNo(operationTaskId); Long firstOperationId = operationTaskMapper.getFirstOperationId(operationTaskId); Long operationId = operationTaskMapper.getOperationIdByTaskId(operationTaskId); // 3.1.根据工单查询投入产出比 List operationTaskMaterialList = operationTaskMaterialMapper.selectList(Wrappers.query().lambda(). eq(OperationTaskMaterial::getOperationTaskId, operationTaskId)); if (CollectionUtil.isNotEmpty(operationTaskMaterialList)) { // 3.2 根据投入比去查询对应的投料数量 WorkstationLocation workstationLocation = workstationLocationMapper.selectOne(Wrappers.lambdaQuery() .eq(WorkstationLocation::getWorkstationId, workstationId) .eq(WorkstationLocation::getLocationType, WorkstationLocation.FED_LOCATION)); if (workstationLocation == null) { throw new RuntimeException("该机台未绑定机台已投料库位"); } for (OperationTaskMaterial operationTaskMaterial : operationTaskMaterialList) { //投入总数量=投入比*产出数量 BigDecimal summary = operationTaskMaterial.getQpa().multiply(productQty); if (summary.compareTo(BigDecimal.ZERO) == 0) { continue; } List stockList = stockMapper.selectList(Wrappers.lambdaQuery() .eq(Stock::getPartId, operationTaskMaterial.getPartId()) .eq(Stock::getLocationId, workstationLocation.getLocationId()) .gt(Stock::getAvailableStockQuantity, BigDecimal.ZERO) .orderByAsc(Stock::getUpdateTime)); // 获取工单所需物料结构 Map> collect = getComponentList(operationTaskId); Part part = partService.getById(operationTaskMaterial.getPartId()); if (collect.get(operationTaskMaterial.getPartId()) == null) { continue; } for (Stock stock : stockList) { String ifsLineItemNo = null; String billNo = RandomStringUtils.random(10, true, true); if (collect.get(stock.getPartId()).get(0).getIfsLineItemNo() != null) { ifsLineItemNo = collect.get(stock.getPartId()).get(0).getIfsLineItemNo(); } // 增加是否为工序库存 setOperationStockStatus(stock, part, operationTaskId); // 工序库存判定 String wpbo = remoteParamService.getByKey(Constant.WORKBEHCH_PR_BP_OSC, SecurityConstants.FROM_IN).getData(); //取消工序库存的限制 if (BooleanUtil.isTrue(stock.getOperationStockStatus()) && !StringUtils.equals(wpbo, "false")) { String stockMoNo = stockMapper.getStockMoNo(stock.getId()); if (!StringUtils.equals(stockMoNo, taskMoNo) && !firstOperationId.equals(operationId)) { continue; } } BigDecimal feedingCost; //库存小于计算量则全部消耗掉 if (stock.getAvailableStockQuantity().compareTo(summary) == -1) { feedingCost = stock.getAvailableStockQuantity(); stockUtils.updateById(stock.getId(), stock.getAvailableStockQuantity().negate(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, billNo, TransactionType.SUBMIT_CONSUME.getValue()); } else { feedingCost = summary; stockUtils.updateById(stock.getId(), summary.negate(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, billNo, TransactionType.SUBMIT_CONSUME.getValue()); } List inputList = new ArrayList<>(); // 判断是否存在相同的组件结构,如果是则生成多份投入 List moStructureComponents = collect.get(stock.getPartId()); if (moStructureComponents.size() > 1) { BigDecimal total = moStructureComponents.stream().map(MoStructureComponent::getQpa).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal inputQty = BigDecimal.ZERO; for (int i = 0; i < moStructureComponents.size(); i++) { ProductInput productInput = productInputMapper.selectOne(Wrappers.lambdaQuery() .eq(ProductInput::getProductMainId, productMainId) .eq(ProductInput::getPartId, stock.getPartId()) .eq(ProductInput::getPartBatchNo, stock.getPartBatchNo()) .eq(ProductInput::getSystemNo, stock.getSystemNo()) .eq(ProductInput::getStockId, stock.getId()) .eq(ProductInput::getIfsLineItemNo, moStructureComponents.get(i).getIfsLineItemNo())); BigDecimal cost = feedingCost.multiply(moStructureComponents.get(i).getQpa()).divide(total, 6, RoundingMode.HALF_UP); // 如果是最后一个,则消耗剩余数量 if (i == moStructureComponents.size() - 1) { cost = feedingCost.subtract(inputQty); } inputQty = inputQty.add(cost); if (productInput == null && cost.compareTo(BigDecimal.ZERO) > 0) { productInput = new ProductInput(); productInput.setInputQuantity(cost); productInput.setIfsLineItemNo(moStructureComponents.get(i).getIfsLineItemNo()); } else { productInput.setInputQuantity(productInput.getInputQuantity().add(cost)); } inputList.add(productInput); } } else { ProductInput productInput = productInputMapper.selectOne(Wrappers.lambdaQuery() .eq(ProductInput::getProductMainId, productMainId) .eq(ProductInput::getPartId, stock.getPartId()) .eq(ProductInput::getPartBatchNo, stock.getPartBatchNo()) .eq(ProductInput::getSystemNo, stock.getSystemNo()) .eq(ProductInput::getStockId, stock.getId()) .eq(ProductInput::getIfsLineItemNo, moStructureComponents.get(0).getIfsLineItemNo())); if (productInput == null) { productInput = new ProductInput(); productInput.setInputQuantity(feedingCost); productInput.setIfsLineItemNo(moStructureComponents.get(0).getIfsLineItemNo()); } else { productInput.setInputQuantity(productInput.getInputQuantity().add(feedingCost)); } inputList.add(productInput); } addOrUpdateProductInput(inputList, stock, productMainId); // 总需消耗减去已消耗 summary = summary.subtract(feedingCost); if (summary.compareTo(BigDecimal.ZERO) == 0) { break; } } } // 如果投入数量不足,则抛出异常 long count = operationTaskMaterialList.stream().map(OperationTaskMaterial::getPartId).distinct().count(); Integer inputNumber = productInputMapper.countPartNumber(productMainId); if (!inputNumber.equals((int) count)) { throw new RuntimeException("投入物料与所需物料数量不符,请补充"); } } } private void queryProductIn(Long productMainId, Long partId, String partBatchNo) { productInputMapper.selectOne(Wrappers.lambdaQuery() .eq(ProductInput::getProductMainId, productMainId).eq(ProductInput::getPartId, partId).eq(ProductInput::getPartBatchNo, partBatchNo)); } @Override public boolean updateProductOutput(ProductMainDTO productMainDTO) { ProductOutputDTO productOutputDTO = productMainDTO.getProductOutputList().get(0); ProductOutput productOutputOriginal = productOutputMapper.selectById(productOutputDTO.getId()); BigDecimal oldProductQty = productOutputOriginal.getProductQty(); BigDecimal oldScrapQty = productOutputOriginal.getScrapQty(); ProductMain productMain = baseMapper.selectById(productOutputOriginal.getProductMainId()); if (ProductMainStateStringValues.SUBMITTED.equals(productMain.getState())) { throw new RuntimeException("报工记录已提交,无法修改"); } //更新产出的数据 BigDecimal productQty = BigDecimal.ZERO; for (ProductOutputDTO productOutput : productMainDTO.getProductOutputList()) { productQty = productQty.add(productOutput.getProductQty()); } checkSegmentDesc(productOutputDTO.getSegmentDesc()); productOutputOriginal.setReelNumber(productOutputDTO.getReelNumber()); productOutputOriginal.setStartMeterMark(productOutputDTO.getStartMeterMark()); productOutputOriginal.setEndMeterMark(productOutputDTO.getEndMeterMark()); productOutputOriginal.setProductQty(productQty); productOutputOriginal.setOutBatchNo(productOutputDTO.getOutBatchNo()); productOutputOriginal.setIfsBatchNo(productOutputDTO.getIfsBatchNo()); productOutputOriginal.setSegmentDesc(productOutputDTO.getSegmentDesc()); productOutputOriginal.setScrapQty(productOutputDTO.getScrapQty()); productOutputOriginal.setRemark(productOutputDTO.getRemark()); productOutputMapper.updateById(productOutputOriginal); //修改投料的数量(投料数量:计算产量+报废数量) BigDecimal incrementQty = oldProductQty.add(oldScrapQty).subtract(productQty).subtract(productOutputOriginal.getScrapQty() == null ? BigDecimal.ZERO : productOutputOriginal.getScrapQty()); if (incrementQty.compareTo(BigDecimal.ZERO) == 1) { // 根据终值去计算投入,不再根据增量去删 autoDeleteInputV2(Collections.singletonList(productMain.getId()), TransactionType.OUTPUT_UPDATE.getValue()); autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), productQty.add(productOutputOriginal.getScrapQty() == null ? BigDecimal.ZERO : productOutputOriginal.getScrapQty())); } else if (incrementQty.compareTo(BigDecimal.ZERO) == -1) { // 自动加投入 autoAddInput(productMain.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), incrementQty.negate()); } //将本次产出的人员全部删除 productOutputStaffMapper.delete(Wrappers.lambdaQuery().eq(ProductOutputStaff::getProductOutId, productOutputDTO.getId())); //将本次产出的人工记录全部删除 List list = artificialInformationMapper.selectList(Wrappers.lambdaQuery().eq(ArtificialInformation::getOutputId, productOutputDTO.getId())); List ids = list.stream().map(ArtificialInformation::getId).collect(Collectors.toList()); backUtils.backDeleteArtificialInformationByIds(ids); artificialInformationMapper.delete(Wrappers.lambdaQuery().eq(ArtificialInformation::getOutputId, productOutputDTO.getId())); for (ProductOutputDTO productOutput : productMainDTO.getProductOutputList()) { //添加人员 addStaff(productOutput); autoBuildArtificialInformation(productOutput.getProductStaffIds(), productOutputDTO.getId(), productOutput.getProductQty(), productOutput.getDutyRecordId(), productOutputOriginal.getPartId(), productMain.getWorkstationId(), productOutput.getOutBatchNo()); } // 更新班次产量 dutyRecordMapper.refreshDutyOutputById(productOutputDTO.getDutyRecordId()); return true; } /** * 报工到人 * * @param productOutput */ private void addStaff(ProductOutputDTO productOutput) { if (CollectionUtil.isNotEmpty(productOutput.getProductStaffIds())) { List staffList = staffMapper.selectList(null); for (Long staff : productOutput.getProductStaffIds()) { ProductOutputStaff outputStaff = new ProductOutputStaff(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); staffList.forEach(a -> { if (a.getId().equals(staff)) { outputStaff.setStaffNo(a.getStaffNo()); } }); outputStaff.setStaffId(staff); outputStaff.setProductOutId(productOutput.getId()); if (productOutput.getSystemNo() == null) { outputStaff.setSystemNo(formatter.format(LocalDateTime.now())); } else { outputStaff.setSystemNo(productOutput.getSystemNo()); } outputStaff.setDate(newFormatter.format(LocalDateTime.now())); outputStaff.setQuantity(productOutput.getProductQty()); outputStaff.setDutyRecordId(productOutput.getDutyRecordId()); outputStaff.setArtificialType(productOutput.getStatus()); productOutputStaffMapper.insert(outputStaff); } } } @Override public ProductOutputDTO getShiftedProductByWidAndOpId(Long workstationId, Long opeartionTaskId) { List productOutputList = productOutputMapper.getShiftProductOutByOpIdAndWsId(workstationId, opeartionTaskId); if (CollectionUtils.isEmpty(productOutputList)) { return null; } else { return productOutputList.get(0); } } @Override public IPage> getList(Page page, QueryWrapper gen) { return baseMapper.getList(page, gen); } @Override public R changeProductOutPutStateByMainId(Long id, String event) { List productOutputs = this.productOutputMapper.selectList(Wrappers.lambdaQuery().eq(ProductOutput::getProductMainId, id)); for (ProductOutput productOutput : productOutputs) { if (("CHANGESHIFTTODRAFT").equals(event)) { Integer selectCount = productOutputMapper.selectCount(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, productOutput.getOutBatchNo()) .gt(ProductOutput::getId, productOutput.getId())); if (selectCount > 0) { throw new RuntimeException("该交班产出已存在接班产出记录"); } } /* if(("DRAFTTOCHANGESHIFT").equals(event)){ List productOutputStaffList = productOutputStaffMapper.selectList(Wrappers.lambdaQuery() .eq(ProductOutputStaff::getProductOutId, productOutput.getId())); List stateList = productOutputMapper.getStateByDutyRecordId(productOutputStaffList.get(0).getDutyRecordId()); if(stateList.contains("03changeshift")){ throw new RuntimeException("同一个班次中,不允许存在多个状态为“交班”状态的报工单存在"); } }*/ Message message = MessageBuilder.withPayload(ProductOutEvents.valueOf(event)).setHeader("productOutput", productOutput).build(); StateMachineHandler handler = new StateMachineHandler(productOutStateMachineFactory, productOutPersister, ProductOutStateMachineConfig.MACHINE_ID, productOutput); StateResult res = handler.sendEvent(message, productOutput.getId()); if (!res.isSuccess()) { return R.failed(res.getMsg()); } } return R.ok(); } @Override public Boolean batchCancelProductMain(List ids) { synchronized (ids.toString().intern()) { List productMains = this.baseMapper.selectBatchIds(ids); if (productMains.size() != ids.size()) { throw new RuntimeException("报工单已删除,请刷新页面"); } boolean processing = productMains.stream().anyMatch(m -> StringUtils.equals(ProductMainStateStringValues.PROCESSING, m.getState())); if (BooleanUtil.isTrue(processing)) { throw new RuntimeException("存在处理中的报工记录,无法删除"); } if (!productMains.isEmpty()) { List productOutputs = this.productOutputMapper.selectList(Wrappers.lambdaQuery().in(ProductOutput::getProductMainId, ids)); if (!productOutputs.isEmpty()) { for (ProductOutput output : productOutputs) { if (!output.getState().equals(ProductOutStateStringValues.DRAFT)) { throw new RuntimeException("存在不是草稿状态下的产出记录无法直接删除"); } // 存在段长来的产出单,需要处理段长批次生成表单 if (output.getIsSnGenerateOutput()) { manufacturingOrderSnGenerateService.updateProduceStatusBySn(output.getOutBatchNo(), false, null); } } this.deleteProductOutputByIds(productOutputs.stream().map(ProductOutput::getId).collect(Collectors.toList())); } for (Long id : ids) { this.cancelProductMainById(id); } // 判断是否存在工步,存在则删除 batchCancelStep(ids); } return true; } } private void batchCancelStep(List ids) { //删除工步 List productStepList = productStepMapper.selectList(Wrappers.lambdaQuery().in(ProductStep::getProductMainId, ids)); if (CollectionUtil.isNotEmpty(productStepList)) { Set productStepIds = productStepList.stream().map(o -> o.getId()).collect(Collectors.toSet()); productStepMapper.delete(Wrappers.lambdaQuery().in(ProductStep::getId, productStepIds)); productStepStaffMapper.delete(Wrappers.lambdaQuery().in(ProductStepStaff::getProductStepId, productStepIds)); } } @Override public Boolean batchChange(List ids, String event) { // List productMains = this.baseMapper.selectBatchIds(ids); // if (!productMains.isEmpty()) { // if (event.equals("REVOKE") || event.equals("CHANGESHIFTTODRAFT")) { // // 更改报工单状态 // for (Long id : ids) { // changeState(id, event); // } // // // 找出报工单下产出,并修改产出状态 // List productOutputs = this.productOutputMapper.selectList(Wrappers.lambdaQuery().in(ProductOutput::getProductMainId, ids)); // if (!productOutputs.isEmpty()) { // List shiftIds = new ArrayList<>(); // List outIds = new ArrayList<>(); // for (ProductOutput productOutput : productOutputs) { // if (productOutput.getState().equals("03changeshift")) { // shiftIds.add(productOutput.getId()); // } else { // outIds.add(productOutput.getId()); // } // } // if (!shiftIds.isEmpty()) { // R r = this.changeProductOutPutState(shiftIds, "CHANGESHIFTTODRAFT"); // if (r.getCode() != 0) { // throw new RuntimeException(r.getMsg() == null ? "产出撤销未成功" : r.getMsg()); // } // } // if (!outIds.isEmpty()) { // R r = this.changeProductOutPutState(outIds, event); // if (r.getCode() != 0) { // throw new RuntimeException(r.getMsg() == null ? "产出撤销未成功" : r.getMsg()); // } // } // } // } else { // // 找出报工单下产出,并修改产出状态 // List productOutputs = this.productOutputMapper.selectList(Wrappers.lambdaQuery().in(ProductOutput::getProductMainId, ids)); // if (!productOutputs.isEmpty()) { // List outIds = productOutputs.stream().filter(out -> !out.getState().equals("03changeshift")).map(ProductOutput::getId).collect(Collectors.toList()); // R r = this.changeProductOutPutState(outIds, event); // if (r.getCode() != 0) { // throw new RuntimeException(r.getMsg() == null ? "产出提交未成功" : r.getMsg()); // } // } // // // 更改报工单状态 // for (Long id : ids) { // changeState(id, event); // } // } // } for (Long id : ids) { //try { // Boolean lock = redisHelper.lock(event + ":" + id); // if (BooleanUtil.isFalse(lock)) { // throw new RuntimeException("当前正在处理中,请稍后刷新页面查看"); // } // ThreadUtil.execute(()->changeState(id, event)); //}finally { // redisHelper.delLock(event + ":" + id); //} //updateProcessing(id); //ThreadUtil.execute(()->changeState(id, event)); changeState(id, event); } return true; } private void updateProcessing(Long id) { ProductMain productMain = productMainMapper.selectById(id); if (StringUtils.equals(ProductMainStateStringValues.PROCESSING, productMain.getState())) { throw new RuntimeException("处理中,请稍后再试"); } productMain.setState(ProductMainStateStringValues.PROCESSING); updateById(productMain); } @Override public String getPrintUrl(Integer type, Long id, String sn) { if (type == 1) { return printUrlUtils.getPrintUrl() + id; } else if (type == 2) { List productOutputs = productOutputMapper.selectList(Wrappers.lambdaQuery().eq(ProductOutput::getProductMainId, id)); return printUrlUtils.getPrintUrl() + productOutputs.get(0).getId(); } else if (type == 3) { return printUrlUtils.getSnPrintUrl() + "sn=" + (StringUtils.isNotBlank(sn) ? sn : ""); } else { List productOutputs = productOutputMapper.selectList(Wrappers.lambdaQuery().eq(ProductOutput::getProductMainId, id)); return printUrlUtils.getSmallPrintUrl() + productOutputs.get(0).getId(); } } @Override public boolean deleteProductOutputByIds(List ids) { //报工判断 List productOutputList = productOutputMapper.selectBatchIds(ids); //查询主表的id List productMainIds = productOutputList.stream().map(ProductOutput::getProductMainId).distinct().collect(Collectors.toList()); //根据报工id 和 提交状态 查询报工主表的数据 Integer productMainCount = getBaseMapper().selectCount(Wrappers.lambdaQuery() .in(ProductMain::getId, productMainIds) .eq(ProductMain::getState, ProductMainStateStringValues.SUBMITTED)); if (productMainCount > 0) { throw new RuntimeException("存在已提交报工,无法修改"); } //查询检测结果的数据判断是否 //SN numbers Set snNumbers = productOutputList.stream().map(productOutput -> productOutput.getSystemNo()).collect(Collectors.toSet()); List resultList = resultMapper.selectList(Wrappers.lambdaQuery().in(Result::getSystemNo, snNumbers)); if (resultList.size() > 0) { if (resultList.stream().filter(result -> result.getIsQualified() != null).count() > 0) { throw new RuntimeException("存在已检测合格的数据,无法修改"); } resultMapper.deleteBatchIds(resultList.stream().map(result -> result.getId()).collect(Collectors.toList())); } //查询检测申请数据 List applyPartList = applyPartMapper.selectList(Wrappers.lambdaQuery().in(ApplyPart::getSystemNo, snNumbers)); if (!CollectionUtils.isEmpty(applyPartList)) { //判断检测申请是否汇报 List applyPartListChecked = applyPartList.stream().filter(e -> null != e.getReportId()).collect(Collectors.toList()); if (CollectionUtils.isEmpty(applyPartListChecked)) { //删除检测申请 List applyIds = applyPartList.stream().map(ApplyPart::getApplyId).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(applyIds)) { applyMapper.deleteBatchIds(applyIds); } //删除检测申请材料 List applyPartIds = applyPartList.stream().map(ApplyPart::getId).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(applyPartIds)) { applyPartMapper.deleteBatchIds(applyPartIds); } } else { throw new RuntimeException("已经存在检测汇报,请先删除检测汇报!"); } } // 删除产出和人工记录 List productOutputStaffList = productOutputStaffMapper.selectList(Wrappers.lambdaQuery().in(ProductOutputStaff::getProductOutId, ids)); productOutputStaffMapper.delete(Wrappers.lambdaQuery().in(ProductOutputStaff::getProductOutId, ids)); //逻辑删除 产出表记录 productOutputMapper.delete(Wrappers.lambdaQuery().in(ProductOutput::getId, ids)); // List artificialInformationList = artificialInformationMapper.selectList(Wrappers.lambdaQuery().in(ArtificialInformation::getOutputId, ids)); // List aids = artificialInformationList.stream().map(ArtificialInformation::getId).collect(Collectors.toList()); backUtils.backDeleteArtificialInformationByIds(aids); artificialInformationMapper.delete(Wrappers.lambdaQuery().in(ArtificialInformation::getOutputId, ids)); // 自动删除投入 (根据报工单删除对应投入,不再重新计算投入) autoDeleteInputV2(productMainIds, TransactionType.INPUT_DELETE.getValue()); // for (ProductOutput productOutput : productOutputList) { // autoDeleteInput(productOutput.getProductMainId(), productOutput.getProductQty()); // } // 更新班次产量 Set dutyRecordIds = productOutputStaffList.stream().map(ProductOutputStaff::getDutyRecordId).collect(Collectors.toSet()); //刷新班次记录 refreshDutyRecord(dutyRecordIds); return true; } @Override public boolean deleteProductOutputById(Long id) { ProductOutput productOutput = productOutputMapper.selectById(id); ProductMain productMain = baseMapper.selectById(productOutput.getProductMainId()); if (ProductMainStateStringValues.SUBMITTED.equals(productMain.getState())) { throw new RuntimeException("报工记录已提交,无法修改"); } Integer resultNum = resultMapper.selectCount(Wrappers.lambdaQuery().eq(Result::getSystemNo, productOutput.getSystemNo()).isNotNull(Result::getIsQualified)); if (resultNum > 0) { throw new RuntimeException("报工已检测无法删除"); } //工作台报工数据删除时需要先校验,是否已经进行了检测汇报 //TODO List applyPartList = applyPartMapper.selectList(Wrappers.lambdaQuery() .eq(ApplyPart::getSystemNo, productOutput.getSystemNo())); if (!CollectionUtils.isEmpty(applyPartList)) { List applyPartListChecked = applyPartList.stream().filter(e -> null != e.getReportId()).collect(Collectors.toList()); if (CollectionUtils.isEmpty(applyPartListChecked)) { //没有进行检测汇报,先删除检测申请数据,再删除报工数据 List applyIds = applyPartList.stream().map(ApplyPart::getApplyId).collect(Collectors.toList()); List applyPartIds = applyPartList.stream().map(ApplyPart::getId).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(applyIds)) { applyMapper.deleteBatchIds(applyIds); } if (!CollectionUtils.isEmpty(applyPartIds)) { applyPartMapper.deleteBatchIds(applyPartIds); } //删除检测结果 //resultMapper.deleteBySystemNo(productOutput.getSystemNo()); resultMapper.deleteAllBySystemNo(productOutput.getSystemNo());//【2022-09-20】 } else { throw new RuntimeException("已经检测汇报,请先删除检测汇报!"); } } // 删除产出和人工记录 List productOutputStaffList = productOutputStaffMapper.selectList(Wrappers.lambdaQuery().eq(ProductOutputStaff::getProductOutId, id)); productOutputStaffMapper.delete(Wrappers.lambdaQuery().eq(ProductOutputStaff::getProductOutId, id)); //逻辑删除 产出表记录 productOutputMapper.deleteById(id); List list = artificialInformationMapper.selectList(Wrappers.lambdaQuery().eq(ArtificialInformation::getOutputId, id)); List ids = list.stream().map(ArtificialInformation::getId).collect(Collectors.toList()); backUtils.backDeleteArtificialInformationByIds(ids); artificialInformationMapper.delete(Wrappers.lambdaQuery().eq(ArtificialInformation::getOutputId, id)); // 自动删除投入 autoDeleteInputV2(Collections.singletonList(productOutput.getProductMainId()), TransactionType.INPUT_DELETE.getValue()); // 更新班次产量 Set dutyRecordIds = productOutputStaffList.stream().map(ProductOutputStaff::getDutyRecordId).collect(Collectors.toSet()); refreshDutyRecord(dutyRecordIds); return true; } /** * 自动删除对应数量的投入 */ public void autoDeleteInput(Long productMainId, BigDecimal productQty) { //删除自动投入 ProductMain productMain = baseMapper.selectById(productMainId); // 1.根据工单查询投入产出比 List operationTaskMaterialList = operationTaskMaterialMapper.selectList(Wrappers.query().lambda(). eq(OperationTaskMaterial::getOperationTaskId, productMain.getOperationTaskId())); if (CollectionUtil.isNotEmpty(operationTaskMaterialList)) { // 2. 根据投入比去查询对应的投入数量 for (OperationTaskMaterial operationTaskMaterial : operationTaskMaterialList) { // 投入总数量=投入比*产出数量 BigDecimal summary = operationTaskMaterial.getQpa().multiply(productQty); List productInputList = productInputMapper.queryList(productMain.getId(), operationTaskMaterial.getPartId()); if (CollectionUtil.isNotEmpty(productInputList)) { for (ProductInputDTO productInputDTO : productInputList) { String billNo = RandomStringUtils.random(10, true, true); // 3. 判断投入的数量是否满足删除的数量 if (productInputDTO.getInputQuantity().compareTo(summary) == 1) { productInputDTO.setInputQuantity(productInputDTO.getInputQuantity().add(summary.negate())); productInputMapper.updateById(productInputDTO); Stock stock = stockMapper.selectById(productInputDTO.getStockId()); //库存记录 stockUtils.createTransaction(stock.getStockQuantity(), summary, stock.getPartId(), stock.getLocationId(), stock.getPartBatchNo(), billNo, TransactionType.PRODUCT_FEEDING.getValue(), stock.getIfsBatchNo()); stock.setStockQuantity(stock.getStockQuantity().add(summary)); stock.setAvailableStockQuantity(stock.getAvailableStockQuantity().add(summary)); stockMapper.updateById(stock); summary = BigDecimal.ZERO; } else { productInputMapper.deleteById(productInputDTO.getId()); Stock stock = stockMapper.selectById(productInputDTO.getStockId()); //库存记录 stockUtils.createTransaction(stock.getStockQuantity(), productInputDTO.getInputQuantity(), stock.getPartId(), stock.getLocationId(), stock.getPartBatchNo(), billNo, TransactionType.PRODUCT_FEEDING.getValue(), stock.getIfsBatchNo()); stock.setStockQuantity(stock.getStockQuantity().add(productInputDTO.getInputQuantity())); stock.setAvailableStockQuantity(stock.getAvailableStockQuantity().add(productInputDTO.getInputQuantity())); stockMapper.updateById(stock); summary = summary.add(productInputDTO.getInputQuantity().negate()); } if (summary.compareTo(BigDecimal.ZERO) != 1) { break; } } } } } } private void autoDeleteInputV2(List productMainIdList, String billType) { List productMains = this.listByIds(productMainIdList); if (CollectionUtil.isNotEmpty(productMains)) { for (ProductMain productMain : productMains) { List productInputs = productInputMapper.selectList(Wrappers.lambdaQuery().eq(ProductInput::getProductMainId, productMain.getId())); if (CollectionUtil.isNotEmpty(productInputs)) { for (ProductInput productInput : productInputs) { Stock stock = stockMapper.selectById(productInput.getStockId()); boolean retBool = SqlHelper.retBool(productInputMapper.deleteById(productInput.getId())); if (retBool) { String billNo = RandomStringUtils.random(10, true, true); stockUtils.updateById(stock.getId(), productInput.getInputQuantity(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, billNo, billType); } } } } } } @Override public Boolean saveProductInput(ProductInputDTO productInputDTO) { String billNo = RandomStringUtils.random(10, true, true); if (productInputDTO.getInputQuantity() == null) { throw new RuntimeException("投入数量不能为空"); } if (productInputDTO.getInputQuantity().compareTo(BigDecimal.ZERO) <= 0) { throw new RuntimeException("投入数量必须大于零"); } ProductMain productMain = baseMapper.selectById(productInputDTO.getProductMainId()); Boolean isChangeshift = judgeChangeshift(productMain.getId()); if (isChangeshift || !ProductMainStateStringValues.DRAFT.equals(productMain.getState())) { throw new RuntimeException("报工记录不是草稿状态,无法修改"); } Stock stock = stockMapper.selectById(productInputDTO.getStockId()); // 查找所需物料信息 String ifsLineItemNo = null; Part part = partService.getById(stock.getPartId()); Map> collect = getComponentList(productMain.getOperationTaskId()); if (collect.get(stock.getPartId()) == null) { throw new RuntimeException("投入物料与所需物料不匹配,请确认"); } else if (collect.get(stock.getPartId()).get(0).getIfsLineItemNo() != null) { ifsLineItemNo = collect.get(stock.getPartId()).get(0).getIfsLineItemNo(); } // 增加是否为工序库存 setOperationStockStatus(stock, part, productMain.getOperationTaskId()); // ProductInput productInput = productInputMapper.selectOne(Wrappers.lambdaQuery() // .eq(ProductInput::getProductMainId, productMain.getId()).eq(ProductInput::getPartId, stock.getPartId()) // .eq(ProductInput::getPartBatchNo, stock.getPartBatchNo()).eq(ProductInput::getSystemNo, stock.getSystemNo()) // .eq(ProductInput::getStockId, stock.getId())); // if (productInput != null) { // throw new RuntimeException("该物料投入已存在,直接修改投入数量,请勿重复投入"); // } stockUtils.createTransaction(stock.getStockQuantity(), productInputDTO.getInputQuantity().negate(), stock.getPartId(), stock.getLocationId(), stock.getPartBatchNo(), billNo, TransactionType.PRODUCT_FEEDING.getValue(), stock.getIfsBatchNo()); //扣除库存 stock.setAvailableStockQuantity(stock.getAvailableStockQuantity().add(productInputDTO.getInputQuantity().negate())); stock.setStockQuantity(stock.getStockQuantity().add(productInputDTO.getInputQuantity().negate())); if (stock.getAvailableStockQuantity().compareTo(BigDecimal.ZERO) == -1) { throw new RuntimeException("投料剩余数量不足"); } stockMapper.updateById(stock); BigDecimal feedingCost = productInputDTO.getInputQuantity(); List inputList = new ArrayList<>(); // 判断是否存在相同的组件结构,如果是则生成多份投入 List moStructureComponents = collect.get(stock.getPartId()); if (moStructureComponents.size() > 1) { BigDecimal total = moStructureComponents.stream().map(MoStructureComponent::getQpa).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal inputQty = BigDecimal.ZERO; for (int i = 0; i < moStructureComponents.size(); i++) { ProductInput productInput = productInputMapper.selectOne(Wrappers.lambdaQuery() .eq(ProductInput::getProductMainId, productMain.getId()) .eq(ProductInput::getPartId, stock.getPartId()) .eq(ProductInput::getPartBatchNo, stock.getPartBatchNo()) .eq(ProductInput::getSystemNo, stock.getSystemNo()) .eq(ProductInput::getStockId, stock.getId()) .eq(ProductInput::getIfsLineItemNo, moStructureComponents.get(i).getIfsLineItemNo())); BigDecimal cost = feedingCost.multiply(moStructureComponents.get(i).getQpa()).divide(total, 2, RoundingMode.HALF_UP); // 如果是最后一个,则消耗剩余数量 if (i == moStructureComponents.size() - 1) { cost = feedingCost.subtract(inputQty); } inputQty = inputQty.add(cost); if (productInput == null) { productInput = new ProductInput(); productInput.setInputQuantity(cost); productInput.setIfsLineItemNo(moStructureComponents.get(i).getIfsLineItemNo()); } else { productInput.setInputQuantity(productInput.getInputQuantity().add(cost)); } inputList.add(productInput); } } else { ProductInput productInput = productInputMapper.selectOne(Wrappers.lambdaQuery() .eq(ProductInput::getProductMainId, productMain.getId()) .eq(ProductInput::getPartId, stock.getPartId()) .eq(ProductInput::getPartBatchNo, stock.getPartBatchNo()) .eq(ProductInput::getSystemNo, stock.getSystemNo()) .eq(ProductInput::getStockId, stock.getId()) .eq(ProductInput::getIfsLineItemNo, moStructureComponents.get(0).getIfsLineItemNo())); if (productInput == null) { productInput = new ProductInput(); productInput.setPartId(stock.getPartId()); productInput.setPartBatchNo(stock.getPartBatchNo()); productInput.setProductMainId(productInputDTO.getProductMainId()); productInput.setInputQuantity(feedingCost); productInput.setIfsLineItemNo(moStructureComponents.get(0).getIfsLineItemNo()); productInput.setSystemNo(stock.getSystemNo()); productInput.setStockId(stock.getId()); productInput.setIfsBatchNo(stock.getIfsBatchNo()); productInput.setOperationStockStatus(stock.getOperationStockStatus()); productInputMapper.insert(productInput); } else { productInput.setInputQuantity(feedingCost); productInputMapper.updateById(productInput); } } addOrUpdateProductInput(inputList, stock, productMain.getId()); // productInput = new ProductInput(); // productInput.setPartId(stock.getPartId()); // productInput.setPartBatchNo(stock.getPartBatchNo()); // productInput.setProductMainId(productInputDTO.getProductMainId()); // productInput.setInputQuantity(productInputDTO.getInputQuantity()); // productInput.setSystemNo(stock.getSystemNo()); // productInput.setStockId(stock.getId()); // productInput.setIfsBatchNo(stock.getIfsBatchNo()); // productInput.setIfsLineItemNo(collect.get(stock.getPartId()).get(0).getIfsLineItemNo()); // productInputMapper.insert(productInput); // return productInput.getId(); return true; } @Override public Map> getComponentList(Long operationTaskId) { // 查找所需物料信息 OperationTask operationTask = operationTaskMapper.selectById(operationTaskId); if (operationTask == null) { throw new RuntimeException("未找到工序任务"); } // 找到当前工艺工序节点 MoRoutingOperation operation = moRoutingOperationMapper.findByOperationTaskId(operationTaskId); MoRoutingOperation beforeOperation = null; // 找到上一个工艺工序节点 if (operation.getOperationOrder() > 1) { beforeOperation = moRoutingOperationMapper.selectOne(Wrappers.lambdaQuery().eq(MoRoutingOperation::getMoId, operation.getMoId()) .eq(MoRoutingOperation::getOperationOrder, operation.getOperationOrder() - 1)); } ManufacturingOrderDTO manufacturingOrderDTO = manufacturingOrderMapper.getOperationSupplyById(operationTaskId).get(0); // RoutingOperation routingOperation = routingOperationMapper.selectById(operationTask.getRoutingOperationId()); // 根据车间订单id,产出零件id,消耗工序id,找到对应的产出组件 (暂时去除消耗工序,产出没有消耗工序) List componentList = moStructureComponentMapper.selectList(Wrappers.lambdaQuery() .eq(MoStructureComponent::getPlanManufacturingOrderId, manufacturingOrderDTO.getId()) .eq(MoStructureComponent::getPartId, operationTask.getPartId()) .and(wrapper -> wrapper.ne(MoStructureComponent::getOperationId, operation.getOperationId()) .or(w -> w.isNull(MoStructureComponent::getOperationId)))); List idList = componentList.stream().map(MoStructureComponent::getId).collect(Collectors.toList()); // 根据产出组件id找出所需物料组件 List needComponentList = moStructureComponentMapper.selectList(Wrappers.lambdaQuery() .in(MoStructureComponent::getParent, idList) .eq(MoStructureComponent::getOperationId, operation.getOperationId())); // 制造订单将上一道工序产出加入投入结构 if (beforeOperation != null) { Long partId = beforeOperation.getPartId(); if (needComponentList.stream().noneMatch(p -> p.getPartId().equals(partId))) { MoStructureComponent join = new MoStructureComponent(); join.setPartId(beforeOperation.getPartId()); join.setQpa(BigDecimal.valueOf(1L)); needComponentList.add(join); } // 修理订单将当前工序产出加入投入结构 } // 注释修理订单,将产出加入投入结构,用户会在组件表中维护进去 //else if ("F".equals(manufacturingOrderDTO.getWorkshopTypeCode())) { // MoStructureComponent join = new MoStructureComponent(); // join.setPartId(operation.getPartId()); // join.setQpa(BigDecimal.valueOf(1L)); // needComponentList.add(join); //} return needComponentList.stream().collect(Collectors.groupingBy(MoStructureComponent::getPartId)); } @Override public IPage> getProductStep(Page page, QueryWrapper gen) { return productStepMapper.getProductStep(page, gen); } @Override public Boolean judgeAddInput(ProductStepDTO productStepDTO) { Boolean type = false; String state = "true"; String key = "FEEF_HINT"; String productionState = "02submitted"; if (state.equals(remoteParamService.getByKey(key, SecurityConstants.FROM_IN).getData())) { int count = productStepMapper.selectCount(Wrappers.lambdaQuery().eq(ProductStep::getSystemNo, productStepDTO.getSystemNo()).eq(ProductStep::getStepId, productStepDTO.getStepId())); if (count > 0) { throw new RuntimeException(productStepDTO.getSystemNo() + "该产出已经经过了该工步的处理"); } ProductOutput productOutput = productOutputMapper.selectOne(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, productStepDTO.getSystemNo())); if (productOutput != null) { ProductMain productMain = baseMapper.selectById(productOutput.getProductMainId()); //if (productMain.getState().equals(productionState)) { // throw new RuntimeException(productStepDTO.getSystemNo() + "对应的产出已提交不可以再修改"); //} OperationJoinStep operationJoinStep = operationJoinStepMapper.getStepById(productStepDTO.getOperationTaskId(), productStepDTO.getStepId()); //根据工单的id查询工序与工步的关联表 List operationJoinStepList = operationJoinStepMapper.getOperationJoinStep(productStepDTO.getOperationTaskId()); if (CollectionUtil.isNotEmpty(operationJoinStepList)) { //判断这道工步的上一步工步是否已经处理 for (OperationJoinStep newOperationJoinStep : operationJoinStepList) { if ((operationJoinStep.getSort() == (newOperationJoinStep.getSort() + 1)) && (operationJoinStep.getSort() != 1)) { int newCount = productStepMapper.selectCount(Wrappers.lambdaQuery().eq(ProductStep::getSystemNo, productStepDTO.getSystemNo()).eq(ProductStep::getStepId, newOperationJoinStep.getTechnologyStepId())); if (newCount == 0) { throw new RuntimeException(productStepDTO.getSystemNo() + "这道工步的上一个工步没有处理"); } } } //判断是否为最后一道工步 // 跳线车间投入已在报工时处理,工步时无需处理 //if (operationJoinStep != null && operationJoinStep.getSort().equals(operationJoinStepList.get(operationJoinStepList.size() - 1).getSort())) { // // 3.1.根据工单查询投入产出比 // List operationTaskMaterialList = operationTaskMaterialMapper.selectList(Wrappers.query().lambda(). // eq(OperationTaskMaterial::getOperationTaskId, productStepDTO.getOperationTaskId())); // if (CollectionUtil.isNotEmpty(operationTaskMaterialList)) { // // 3.2 根据投入比去查询对应的投料数量 // WorkstationLocation workstationLocation = workstationLocationMapper.selectOne(Wrappers.lambdaQuery() // .eq(WorkstationLocation::getWorkstationId, productMain.getWorkstationId()) // .eq(WorkstationLocation::getLocationType, WorkstationLocation.FED_LOCATION)); // if (workstationLocation == null) { // throw new RuntimeException("该机台未绑定机台已投料库位"); // } // for (OperationTaskMaterial operationTaskMaterial : operationTaskMaterialList) { // //投入总数量=投入比*产出数量 // BigDecimal summary = operationTaskMaterial.getQpa().multiply(BigDecimal.ONE); // List stockList = stockMapper.selectList(Wrappers.lambdaQuery() // .eq(Stock::getPartId, operationTaskMaterial.getPartId()) // .eq(Stock::getLocationId, workstationLocation.getLocationId()) // .gt(Stock::getAvailableStockQuantity, BigDecimal.ZERO)); // // 获取工单所需物料结构 // Map> collect = getComponentList(productMain.getOperationTaskId()); // if (collect.get(operationTaskMaterial.getPartId()) == null) { // continue; // } // for (Stock stock : stockList) { // BigDecimal feedingCost; // //库存小于计算量 // if (stock.getAvailableStockQuantity().compareTo(summary) == -1) { // feedingCost = stock.getAvailableStockQuantity(); // } else { // feedingCost = summary; // } // // // 总需消耗减去已消耗 // summary = summary.subtract(feedingCost); // if (summary.compareTo(BigDecimal.ZERO) == 0) { // break; // } // } // // // 料不足,不允许新增产出 // if (summary.compareTo(BigDecimal.ZERO) == 1) { // type = true; // break; // } // } // } //} } } else { throw new RuntimeException(productStepDTO.getSystemNo() + "不存在该产出,请核对SN码"); } } return type; } @Override public List getGenerateSN(Long operationTaskId) { List result = new ArrayList<>(); List orders = manufacturingOrderMapper.getOperationSupplyById(operationTaskId); if (orders.size() > 0) { // 根据理论消耗表找出成品车间订单 MasterProductionScheduleTheoryQuantity theoryQuantity = theoryQuantityMapper.selectOne( Wrappers.lambdaQuery() .eq(MasterProductionScheduleTheoryQuantity::getMid, orders.get(0).getMpsId()) .eq(MasterProductionScheduleTheoryQuantity::getIsMaster, true)); if (theoryQuantity != null) { // 找出所有成品车间订单 List manufacturingOrders = manufacturingOrderMapper.selectList( Wrappers.lambdaQuery() .eq(ManufacturingOrder::getScheduleTheoryQuantityId, theoryQuantity.getId())); if (manufacturingOrders.size() > 0) { for (ManufacturingOrder manufacturingOrder : manufacturingOrders) { List generateList = manufacturingOrderSnGenerateMapper.selectListByMoId(manufacturingOrder.getId()); if (!generateList.isEmpty()) { // 找出父级递归 for (ManufacturingOrderSnGenerateDTO generateDTO : generateList) { if (generateDTO.getParentId() == null) { recursionSN(result, generateList, generateDTO); } } } } } } } return result; } private void recursionSN(List result, List generateList, ManufacturingOrderSnGenerateDTO generateDTO) { if (generateDTO.getParentId() == null) { result.add(generateDTO); } for (ManufacturingOrderSnGenerateDTO dto : generateList) { if (dto.getParentId() != null) { if (dto.getParentId().equals(generateDTO.getId())) { if (generateDTO.getChildren() != null) { generateDTO.getChildren().add(dto); } else { generateDTO.setChildren(new ArrayList<>()); generateDTO.getChildren().add(dto); } recursionSN(result, generateList, dto); } } } } @Override public List exportList(Long operationTaskId, Long workstationId) { return productOutputMapper.exportList(operationTaskId, workstationId); } private void addOrUpdateProductInput(List productInputs, Stock stock, Long mainId) { //同一个零件同一批次存在记录,则在上面累加投入,否则新建一条记录 for (ProductInput productInput : productInputs) { if (productInput.getId() != null) { productInputMapper.updateById(productInput); } else { productInput.setPartId(stock.getPartId()); productInput.setPartBatchNo(stock.getPartBatchNo()); productInput.setProductMainId(mainId); productInput.setSystemNo(stock.getSystemNo()); productInput.setStockId(stock.getId()); productInput.setIfsBatchNo(stock.getIfsBatchNo()); productInput.setOperationStockStatus(stock.getOperationStockStatus()); productInputMapper.insert(productInput); } } } @Override public boolean updateProductInput(ProductInput productInput) { String billNo = RandomStringUtils.random(10, true, true); if (productInput.getInputQuantity() == null) { throw new RuntimeException("投入数量不能为空"); } if (productInput.getInputQuantity().compareTo(BigDecimal.ZERO) <= 0) { throw new RuntimeException("投入数量必须大于零"); } ProductInput productInputOriginal = productInputMapper.selectById(productInput.getId()); ProductMain productMain = baseMapper.selectById(productInputOriginal.getProductMainId()); Boolean isChangeshift = judgeChangeshift(productMain.getId()); if (isChangeshift || !ProductMainStateStringValues.DRAFT.equals(productMain.getState())) { throw new RuntimeException("报工记录不是草稿状态,无法修改"); } productInputMapper.updateById(productInput); BigDecimal changeQuantity = productInputOriginal.getInputQuantity().subtract(productInput.getInputQuantity()); Stock stock = stockMapper.selectById(productInputOriginal.getStockId()); stockUtils.createTransaction(stock.getStockQuantity(), changeQuantity, stock.getPartId(), stock.getLocationId(), stock.getPartBatchNo(), billNo, TransactionType.PRODUCT_FEEDING.getValue(), stock.getIfsBatchNo()); stock.setStockQuantity(stock.getStockQuantity().add(changeQuantity)); stock.setAvailableStockQuantity(stock.getAvailableStockQuantity().add(changeQuantity)); if (stock.getAvailableStockQuantity().compareTo(BigDecimal.ZERO) == -1) { throw new RuntimeException("投料剩余数量不足"); } stockMapper.updateById(stock); return true; } @Override public boolean deleteProductInputById(Long id) { String billNo = RandomStringUtils.random(10, true, true); ProductInput productInput = productInputMapper.selectById(id); if (productInput != null) { ProductMain productMain = baseMapper.selectById(productInput.getProductMainId()); List operationTaskMaterials = operationTaskMaterialMapper.getMaterial(Wrappers.lambdaQuery() .eq(OperationTaskMaterialDTO::getOperationTaskId, productMain.getOperationTaskId())); if (operationTaskMaterials == null) { throw new RuntimeException("工单所需物料为空"); } List ProductInputDTOList = productInputMapper.queryListByDelete(productInput.getProductMainId(), productInput.getId()); if (CollectionUtil.isEmpty(ProductInputDTOList)) { throw new RuntimeException("当前删除的物料是最后一条"); } List partNoList = ProductInputDTOList.stream().map(ProductInputDTO::getPartNo).collect(Collectors.toList()); Set operationPartNoList = operationTaskMaterials.stream().map(OperationTaskMaterialDTO::getPartNo).collect(Collectors.toSet()); if (!partNoList.containsAll(operationPartNoList)) { throw new RuntimeException("当前删除的物料是最后一条"); } Boolean isChangeshift = judgeChangeshift(productMain.getId()); if (isChangeshift || !ProductMainStateStringValues.DRAFT.equals(productMain.getState())) { throw new RuntimeException("报工记录不是草稿状态,无法修改"); } Stock stock = stockMapper.selectById(productInput.getStockId()); stockUtils.createTransaction(stock.getStockQuantity(), productInput.getInputQuantity(), stock.getPartId(), stock.getLocationId(), stock.getPartBatchNo(), billNo, TransactionType.PRODUCT_CANCEL.getValue(), stock.getIfsBatchNo()); stock.setAvailableStockQuantity(stock.getAvailableStockQuantity().add(productInput.getInputQuantity())); stock.setStockQuantity(stock.getStockQuantity().add(productInput.getInputQuantity())); stockMapper.updateById(stock); productInputMapper.deleteById(id); } return true; } @Override public IPage getOutputList(Page page, QueryWrapper gen, ProductOutputDTO productOutputDTO) { ProductOutputDTO searchProductOutputDTO = new ProductOutputDTO(); BeanUtils.copyProperties(productOutputDTO, searchProductOutputDTO); productOutputDTO.setStartTime(null); productOutputDTO.setEndTime(null); IPage outputList = productOutputMapper.getOutputList(page, QueryWrapperUtil.gen(productOutputDTO), searchProductOutputDTO); if (!outputList.getRecords().isEmpty()) { boolean orderBy = productOutputDTO.getCriteria().contains("orderBy"); if (orderBy) { JSONObject json = JSONObject.parseObject(productOutputDTO.getCriteria()); json.remove("orderBy"); productOutputDTO.setCriteria(json.toJSONString()); } BigDecimal sum = productOutputMapper.getSumProductQty(QueryWrapperUtil.gen(productOutputDTO), searchProductOutputDTO); ProductOutputDTO out = new ProductOutputDTO(); out.setStaffName(""); out.setProductQty(sum); outputList.getRecords().add(out); } return outputList; } @Override public List getOutputListByScan(ProductOutputDTO productOutputDTO) { List outputList = productOutputMapper.getOutputListByScan(productOutputDTO); return outputList; } @Override public List getStep(Long id) { return stepMapper.getStep(id); } @Override public List getProductStep(Long id) { return stepMapper.getProductStep(id); } @Override public List getProductStepBySn(Long id, String sn) { return stepMapper.getProductStepBySn(id, sn); } @Override public ProductStepDTO getAllProductStep(Long id) { ProductStepDTO productStepDTO = productStepMapper.getById(id); List stepDTOList = stepMapper.getAllProductStep(id); productStepDTO.setStepDTOList(stepDTOList); return productStepDTO; } @Override public List addOrUpdateStep(ProductStepDTO productStepDTO) { Boolean lock = redisHelper.lock(productStepDTO.getSystemNo() + "-" + productStepDTO.getStepId()); if (BooleanUtil.isFalse(lock)) { throw new RuntimeException("已有相同工单工步在执行,稍后刷新页面再试"); } try { int count = productStepMapper.selectCount(Wrappers.lambdaQuery().eq(ProductStep::getSystemNo, productStepDTO.getSystemNo()).eq(ProductStep::getStepId, productStepDTO.getStepId())); if (count > 0) { throw new RuntimeException(productStepDTO.getSystemNo() + "该产出已经经过了该工步的处理"); } ProductOutput productOutput = productOutputMapper.selectOne(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, productStepDTO.getSystemNo())); ProductMain productMain = baseMapper.selectById(productOutput.getProductMainId()); if (productMain.getOperationTaskId().compareTo(productStepDTO.getOperationTaskId()) != 0) { throw new RuntimeException(productStepDTO.getSystemNo() + "该产出不属于当前工单,请重新确认"); } DutyRecord dutyRecord = dutyRecordMapper.selectOne(Wrappers.lambdaQuery().eq(DutyRecord::getDutyNo, productStepDTO.getDutyNo())); JoinStepTemplate joinStepTemplate = joinStepTemplateMapper.selectOne(Wrappers.lambdaQuery().eq(JoinStepTemplate::getStepId, productStepDTO.getStepId())); if (joinStepTemplate != null) { List operationTaskRecordDTOList = operationTaskRecordMapper.getAllTemplateRecord(productStepDTO.getOperationTaskId(), joinStepTemplate.getTemplateId(), dutyRecord.getId()); if (CollectionUtil.isEmpty(operationTaskRecordDTOList)) { throw new RuntimeException(productStepDTO.getSystemNo() + "该工步对应的生产记录没有填写,请填写后继续操作"); } } ProductStep productStep = new ProductStep(); productStep.setOperationTaskId(productStepDTO.getOperationTaskId()); productStep.setStepId(productStepDTO.getStepId()); productStep.setProductMainId(productOutput.getProductMainId()); productStep.setSystemNo(productStepDTO.getSystemNo()); if (productOutput != null) { productStep.setStepBatchNo(productOutput.getOutBatchNo()); } productStepMapper.insert(productStep); for (ProductStepStaff newProductStepStaff : productStepDTO.getStepStaffList()) { ProductStepStaff productStepStaff = new ProductStepStaff(); productStepStaff.setStaffId(newProductStepStaff.getStaffId()); productStepStaff.setProductStepId(productStep.getId()); productStepStaffMapper.insert(productStepStaff); } //根据工单的id和工步的id查询工序与工步的关联表 // 跳线报工单提交不在最后一个工步处理,已提前提交处理 //OperationJoinStep operationJoinStep = operationJoinStepMapper.getStepById(productStepDTO.getOperationTaskId(), productStepDTO.getStepId()); ////根据工单的id查询工序与工步的关联表 //List operationJoinStepList = operationJoinStepMapper.getOperationJoinStep(productStepDTO.getOperationTaskId()); //if (CollectionUtil.isNotEmpty(operationJoinStepList)) { // if (operationJoinStep != null && operationJoinStep.getSort().equals(operationJoinStepList.get(operationJoinStepList.size() - 1).getSort())) { // if (productOutput != null) { // productMain.setState(ProductMainStateStringValues.PROCESSING); // updateById(productMain); // productOutput.setProductQty(BigDecimal.ONE); // productOutputMapper.updateById(productOutput); // List ids = new ArrayList<>(); // ids.add(productOutput.getProductMainId()); // if (productMain != null) { // autoAddInput(productStepDTO.getOperationTaskId(), productMain.getWorkstationId(), productMain.getId(), productOutput.getProductQty()); // } // batchChange(ids, "SUBMIT"); // } // } //} //查询工装模具,如果存在工步对应的模具就新增使用记录 ThreadUtil.execute(() -> addMouldUseOrder(productStepDTO, productMain.getProductNo(), productOutput.getOutBatchNo())); return productStepMapper.getStepById(productStep.getOperationTaskId(), productStep.getStepId(), productMain.getId()); } finally { redisHelper.delLock(productStepDTO.getSystemNo() + "-" + productStepDTO.getStepId()); } } public synchronized void addMouldUseOrder(ProductStepDTO productStepDTO, String productNo, String outBatchNo) { List mouldRegisterList = mouldRegisterMapper.selectList(Wrappers.lambdaQuery().eq(MouldRegister::getWorkstationId, productStepDTO.getWorkstationId()).eq(MouldRegister::getStepId, productStepDTO.getStepId())); if (CollectionUtil.isNotEmpty(mouldRegisterList)) { for (MouldRegister mouldRegister : mouldRegisterList) { MouldUseRecord mouldUseRecord = new MouldUseRecord(); mouldUseRecord.setMouldRegisterId(mouldRegister.getId()); mouldUseRecord.setBatchNo(outBatchNo); mouldUseRecord.setOperationTaskId(productStepDTO.getOperationTaskId()); mouldUseRecord.setOutput(BigDecimal.ONE); mouldUseRecord.setProductNo(productNo); mouldUseRecord.setUsageAmount(BigDecimal.ONE.multiply(mouldRegister.getLifeConversionFactor())); mouldUseRecord.setStatus("未提交"); mouldUseRecord.setWorkstationId(productStepDTO.getWorkstationId()); mouldUseRecordMapper.insert(mouldUseRecord); } } } @Override public boolean deleteProductStep(Long id) { ProductStep productStep = productStepMapper.selectById(id); if (productStep != null) { //根据工单的id和工步的id查询工序与工步的关联表 OperationJoinStep operationJoinStep = operationJoinStepMapper.getStepById(productStep.getOperationTaskId(), productStep.getStepId()); //根据工单的id查询工序与工步的关联表 List operationJoinStepList = operationJoinStepMapper.getOperationJoinStep(productStep.getOperationTaskId()); ProductOutput productOutput = productOutputMapper.selectOne(Wrappers.lambdaQuery().eq(ProductOutput::getSystemNo, productStep.getSystemNo())); if (CollectionUtil.isNotEmpty(operationJoinStepList)) { //判断下一道工步是否已经执行,如果执行了当前工步不可删除 for (OperationJoinStep newOperationJoinStep : operationJoinStepList) { if (newOperationJoinStep.getSort() == operationJoinStep.getSort() + 1) { ProductStep nweProductStep = productStepMapper.selectOne(Wrappers.lambdaQuery().eq(ProductStep::getSystemNo, productStep.getSystemNo()).eq(ProductStep::getStepId, newOperationJoinStep.getTechnologyStepId())); if (nweProductStep != null) { throw new RuntimeException(productStep.getSystemNo() + "的下一道工步已经处理,请先删除下一道工步"); } } } //判断是否为最后一道工步 if (operationJoinStep != null && operationJoinStep.getSort().equals(operationJoinStepList.get(operationJoinStepList.size() - 1).getSort())) { if (productOutput != null) { List ids = new ArrayList<>(); ids.add(productOutput.getId()); changeProductOutPutState(ids, "REVOKE"); productOutput.setProductQty(BigDecimal.ZERO); productOutput.setState(ProductOutStateStringValues.DRAFT); productOutputMapper.updateById(productOutput); autoDeleteInputV2(Collections.singletonList(productOutput.getProductMainId()), TransactionType.INPUT_DELETE.getValue()); } } } } productStepMapper.deleteById(id); productStepStaffMapper.delete(Wrappers.lambdaQuery().eq(ProductStepStaff::getProductStepId, id)); //删除工步的同时,更改对应的模具使用记录 ThreadUtil.execute(() -> deleteMouldUseOrder(productStep)); return true; } @Override public IPage> getProductOut(Page page, QueryWrapper gen, Long id) { return productOutputMapper.getProductOut(page, gen, id); } @Override public R changeProductOutPutState(List ids, String event) { if (CollectionUtil.isNotEmpty(ids)) { for (Long id : ids) { ProductOutput productOutput = productOutputMapper.selectById(id); Message message = MessageBuilder.withPayload(ProductOutEvents.valueOf(event)).setHeader("productOutput", productOutput).build(); StateMachineHandler handler = new StateMachineHandler(productOutStateMachineFactory, productOutPersister, ProductOutStateMachineConfig.MACHINE_ID, productOutput); StateResult res = handler.sendEvent(message, productOutput.getId()); if (!res.isSuccess()) { return R.failed(res.getMsg()); } } } return R.ok(); } /** * 刷新班次产量字段 * * @param dutyRecordIds */ private void refreshDutyRecord(Set dutyRecordIds) { if (CollectionUtil.isNotEmpty(dutyRecordIds)) { dutyRecordIds.stream().forEach(dutyRecordId -> { dutyRecordMapper.refreshDutyOutputById(dutyRecordId); }); } } private void setOperationStockStatus(Stock stock, Part part, Long operationTaskId) { if (stock.getOperationStockStatus() == null) { // 原材料(通过查零件基础表的【零件类型】为‘已采购(原材料)’且【计划方法】为‘A’),【是否工序库存】字段默认为‘否’ if (part.getMaterialType().equals("3") && part.getPlanningMethod().equals("A")) { stock.setOperationStockStatus(false); } } } public synchronized void deleteMouldUseOrder(ProductStep productStep) { ProductMain productMain = baseMapper.selectById(productStep.getProductMainId()); List mouldRegisterList = mouldRegisterMapper.selectList(Wrappers.lambdaQuery().eq(MouldRegister::getStepId, productStep.getStepId()).eq(MouldRegister::getWorkstationId, productMain.getWorkstationId())); if (CollectionUtil.isNotEmpty(mouldRegisterList)) { for (MouldRegister mouldRegister : mouldRegisterList) { MouldUseRecord mouldUseRecord = mouldUseRecordMapper.selectOne(Wrappers.lambdaQuery().eq(MouldUseRecord::getProductNo, productMain.getProductNo()).eq(MouldUseRecord::getMouldRegisterId, mouldRegister.getId())); if (mouldUseRecord != null) { BigDecimal number = mouldUseRecord.getUsageAmount(); mouldUseRecord.setUsageAmount(number.subtract(BigDecimal.ONE.multiply(mouldRegister.getLifeConversionFactor()))); mouldUseRecordMapper.updateById(mouldUseRecord); } } } } @Override public List getGenerateSnByCustomerOrderNo(String customerOrderNo) { return manufacturingOrderSnGenerateMapper.getProductSnsByCustomerOrderNo("%" + customerOrderNo + "%"); } @Override public String getSNByTaskId(Long taskId) { return manufacturingOrderMapper.getSNByTaskId(taskId); } @Override public long getOutputByBatchNo(String outBatchNo) { return productOutputMapper.selectCount(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, outBatchNo)); } @Override public Boolean batchLabelPrintTimes(List ids) { updateLabelPrintTimes(ids); return true; } @Override public Boolean checkBatchLabelPrint(List ids, Boolean isSubmit) { List outputList = productOutputMapper.selectList(Wrappers.lambdaQuery() .in(ProductOutput::getId, ids)); for (ProductOutput productOutput : outputList) { if (productOutput.getPrintNum() == null) { productOutput.setPrintNum(1L); } else { return false; } } if (!isSubmit) { productOutputService.updateBatchById(outputList); } return true; } @Override public R checkLabelPrintPassword(String password, List ids, Boolean isSubmit) { String res = remoteParamService.getByKey(WORKBENCH_LABEL_REPRINT, SecurityConstants.FROM_IN).getData(); if (null == password || password.length() == 0) { return R.failed("密码不可为空"); } if (null == res) { return R.failed("密码验证失败"); } if (!res.equals(password)) { return R.failed("密码错误"); } //密码校验通过后,更新打印次数 if (!isSubmit) { updateLabelPrintTimes(ids); } return R.ok(); } @Override public R updatePrintNum(List ids) { updateLabelPrintTimes(ids); return R.ok(); } @Override public List batchLabelPrint(List ids) { return productOutputMapper.batchLabelPrint(ids); } @Override public List getPartNamesByOrderNo(String customerOrderNo) { return customerOrderMapper.getPartNamesByOrderNo(customerOrderNo); } @Override public List getProductSnByCustomerNoAndPartName(String customerOrderNo, String partName) { return manufacturingOrderSnGenerateMapper.getProductSnByCustomerNoAndPartName(customerOrderNo, partName); } @Override public R validateOverProduction(List productMainDTOList) { BigDecimal outQty = BigDecimal.ZERO; Long taskId = productMainDTOList.get(0).getOperationTaskId(); List oriOutputList = productOutputMapper.selectByTaskId(taskId); List mains = new ArrayList<>(); Set oriMainIdSet = new HashSet<>(); if (productMainDTOList.get(0).getId() != null) { mains = productMainDTOList; oriMainIdSet = mains.stream().map(ProductMain::getId).collect(Collectors.toSet()); } else { for (ProductMainDTO productMainDTO : productMainDTOList) { for (int i = 0; i < productMainDTO.getDiscsNumber(); i++) { ProductMainDTO productMain = new ProductMainDTO(); productMain.setOperationTaskId(productMainDTO.getOperationTaskId()); productMain.setWorkstationId(productMainDTO.getWorkstationId()); productMain.setProductOutputList(productMainDTO.getProductOutputList()); productMain.setIsChangeShift(productMainDTO.getIsChangeShift()); productMain.setState(ProductMainStateStringValues.DRAFT); mains.add(productMain); } } } // 排除更新数据,汇总原有产出数量 Set finalOriMainIdSet = oriMainIdSet; BigDecimal oriProductQty = oriOutputList.stream().filter(o -> !finalOriMainIdSet.contains(o.getProductMainId())).map(ProductOutput::getProductQty).reduce(BigDecimal.ZERO, BigDecimal::add); for (ProductMainDTO productMainDTO : mains) { outQty = outQty.add(productMainDTO.getProductOutputList().stream().map(p -> p.getEndMeterMark().subtract(p.getStartMeterMark())) .reduce(BigDecimal.ZERO, BigDecimal::add)); } OperationTask operationTask = operationTaskMapper.selectById(taskId); BigDecimal outputQty = operationTask.getCompletedQuantity().add(outQty).add(oriProductQty); if (outputQty.compareTo(operationTask.getPlannedQuantity().multiply(new BigDecimal("0.05").add(BigDecimal.ONE))) >= 0) { return R.ok(ValidateOverProductionDTO.builder().success(Boolean.FALSE) .message("最多可报工" + operationTask.getPlannedQuantity().multiply(new BigDecimal("0.05").add(BigDecimal.ONE)) + ",当前报工总量" + outputQty + ",已超报,请班组长输入密码确认").build()); } return R.ok(ValidateOverProductionDTO.builder().success(Boolean.TRUE).build()); } @Override public R checkRawPart(List partNoList) { String checkInputType = remoteParamService.getByKey(Constant.CHECK_INPUT_TYPE, SecurityConstants.FROM_IN).getData(); if (StringUtils.equals(checkInputType, "false")) { return R.ok(CheckRawPartDTO.builder().success(Boolean.TRUE).build()); } if (CollectionUtil.isEmpty(partNoList)) { throw new RuntimeException("零件号不能为空"); } Set noMaterialpartNoList = new HashSet<>(); for (String partNo : partNoList) { Part part = partService.getOne(Wrappers.lambdaQuery() .eq(Part::getPartNo, partNo) .eq(Part::getMaterialType, "3")); if (part == null) { noMaterialpartNoList.add(partNo); } } if (CollectionUtil.isEmpty(noMaterialpartNoList)) { return R.ok(CheckRawPartDTO.builder().success(Boolean.TRUE).build()); } else { return R.ok(CheckRawPartDTO.builder().success(Boolean.FALSE).message("以下零件号不是原材料" + noMaterialpartNoList.toString()).build()); } } /** * 校验当前报工投料是否充足 * * @param productMainDTOList * @return */ @Override public R validateOverFeed(List productMainDTOList) { //校验要不要进行投料判断 String checkInputLimit = remoteParamService.getByKey(Constant.WORKBEHCH_PR_BP_CIQ, SecurityConstants.FROM_IN).getData(); if (StringUtils.equals(checkInputLimit, "false")) { return R.ok(ValidateOverFeedResultDTO.builder().success(Boolean.TRUE).build()); } //投料判断 List mains = new ArrayList<>(); Set oriMainIdSet = new HashSet<>(); BigDecimal oriProductQty = BigDecimal.ZERO; if (productMainDTOList.get(0).getId() != null) { mains = productMainDTOList; oriMainIdSet = mains.stream().map(ProductMain::getId).collect(Collectors.toSet()); List oriOutputList = productOutputMapper.selectList(Wrappers.lambdaQuery().in(ProductOutput::getProductMainId, oriMainIdSet)); oriProductQty = oriOutputList.stream().map(p -> BigDecimalUtils.getBigDecimalValue(p.getProductQty()) .add(BigDecimalUtils.getBigDecimalValue(p.getScrapQty()))).reduce(BigDecimal.ZERO, BigDecimal::add); } else { for (ProductMainDTO productMainDTO : productMainDTOList) { for (int i = 0; i < productMainDTO.getDiscsNumber(); i++) { ProductMainDTO productMain = new ProductMainDTO(); productMain.setOperationTaskId(productMainDTO.getOperationTaskId()); productMain.setWorkstationId(productMainDTO.getWorkstationId()); productMain.setProductOutputList(productMainDTO.getProductOutputList()); productMain.setIsChangeShift(productMainDTO.getIsChangeShift()); productMain.setState(ProductMainStateStringValues.DRAFT); mains.add(productMain); } } } BigDecimal productQty = BigDecimal.ZERO; for (ProductMainDTO mainDTO : mains) { productQty = productQty.add(mainDTO.getProductOutputList().stream().map(p -> BigDecimalUtils.getBigDecimalValue(p.getEndMeterMark()) .subtract(BigDecimalUtils.getBigDecimalValue(p.getStartMeterMark())) .add(BigDecimalUtils.getBigDecimalValue(p.getScrapQty()))) .reduce(BigDecimal.ZERO, BigDecimal::add)); } Long operationTaskId = mains.get(0).getOperationTaskId(); Long workStationId = mains.get(0).getWorkstationId(); Step step = stepMapper.getFirstStep(operationTaskId); if (step != null) { return R.ok(ValidateOverFeedResultDTO.builder().success(Boolean.TRUE).build()); } String taskMoNo = operationTaskMapper.getTaskMoNo(productMainDTOList.get(0).getOperationTaskId()); // 根据工单找到对应车间订单的第一道工序id Long firstOperationId = operationTaskMapper.getFirstOperationId(productMainDTOList.get(0).getOperationTaskId()); // 找到当前工单对应的工序id Long operationId = operationTaskMapper.getOperationIdByTaskId(productMainDTOList.get(0).getOperationTaskId()); // 根据工单查询投入产出比 List operationTaskMaterialList = operationTaskMaterialMapper.selectList(Wrappers.query().lambda(). eq(OperationTaskMaterial::getOperationTaskId, operationTaskId)); // 按照partId分组 Map taskMaterialMap = operationTaskMaterialList.stream().collect(Collectors.toMap(OperationTaskMaterial::getPartId, taskMaterial -> taskMaterial, (v1, v2) -> v2)); if (CollectionUtil.isEmpty(operationTaskMaterialList)) { return R.ok(ValidateOverFeedResultDTO.builder().success(Boolean.TRUE).build()); } WorkstationLocation workstationLocation = workstationLocationMapper.selectOne(Wrappers.lambdaQuery() .eq(WorkstationLocation::getWorkstationId, workStationId) .eq(WorkstationLocation::getLocationType, WorkstationLocation.FED_LOCATION)); if (workstationLocation == null) { throw new RuntimeException("该机台未绑定机台已投料库位"); } // 所需所有零件id Set partIdSet = operationTaskMaterialList.stream().filter(o -> o.getPartId() != null).map(OperationTaskMaterial::getPartId).collect(Collectors.toSet()); List stockList = stockMapper.selectList(Wrappers.lambdaQuery() .in(Stock::getPartId, partIdSet) .eq(Stock::getLocationId, workstationLocation.getLocationId()) .gt(Stock::getAvailableStockQuantity, BigDecimal.ZERO)); // 获取所有零件 List partList = partService.list(Wrappers.lambdaQuery().in(Part::getId, partIdSet)); Map partMap = partList.stream().collect(Collectors.toMap(Part::getId, part -> part, (v1, v2) -> v2)); List availableStockList = new ArrayList<>(); for (Stock stock : stockList) { Part part = partMap.get(stock.getPartId()); setOperationStockStatus(stock, part, operationTaskId); if (BooleanUtil.isTrue(stock.getOperationStockStatus())) { String stockMoNo = stockMapper.getStockMoNo(stock.getId()); if (!StringUtils.equals(stockMoNo, taskMoNo) && !firstOperationId.equals(operationId)) { continue; } } availableStockList.add(stock); } Map> stockMap = availableStockList.stream().collect(Collectors.groupingBy(Stock::getPartId)); // 计算各零件所需数量和已有库存数量 List overFeedDTOS = new ArrayList<>(); for (Map.Entry entry : taskMaterialMap.entrySet()) { OperationTaskMaterial taskMaterial = entry.getValue(); BigDecimal costQuantity = taskMaterial.getQpa().multiply(productQty); BigDecimal stockQuantity = BigDecimal.ZERO; if (stockMap.containsKey(taskMaterial.getPartId())) { stockQuantity = stockMap.get(taskMaterial.getPartId()).stream().map(Stock::getAvailableStockQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); // 将修改的原有报工所需材料还原回去 stockQuantity = stockQuantity.add(oriProductQty.multiply(taskMaterial.getQpa())); } ValidateOverFeedDTO overFeedDTO = ValidateOverFeedDTO.builder().partName(partMap.get(taskMaterial.getPartId()).getPartName()) .costQuantity(costQuantity).stockQuantity(stockQuantity).build(); overFeedDTOS.add(overFeedDTO); } List overFeeds = overFeedDTOS.stream().filter(feedDto -> feedDto.getCostQuantity().compareTo(feedDto.getStockQuantity()) > 0).collect(Collectors.toList()); List resultMsg = new ArrayList<>(); if (CollectionUtil.isNotEmpty(overFeeds)) { resultMsg = overFeeds.stream().map(f -> ("物料【" + f.getPartName() + "】" + "已有库存数量【" + f.getStockQuantity() + "】,所需数量【" + f.getCostQuantity() + "】")).collect(Collectors.toList()); } if (CollectionUtil.isNotEmpty(resultMsg)) { return R.ok(ValidateOverFeedResultDTO.builder().success(Boolean.FALSE).message(resultMsg).build()); } return R.ok(ValidateOverFeedResultDTO.builder().success(Boolean.TRUE).build()); } @Override public R process(List ids) { List productMainList = productMainMapper.selectBatchIds(ids); boolean b = productMainList.stream().anyMatch(s -> !StringUtils.equals(ProductMainStateStringValues.DRAFT, s.getState())); if (BooleanUtil.isTrue(b)) { throw new RuntimeException("存在非草稿状态报工单,无法提交"); } productMainList.forEach(p -> p.setState(ProductMainStateStringValues.PROCESSING)); updateBatchById(productMainList); return R.ok(); } @Override public Boolean validateIsLastOperation(Long id) { return operationTaskMapper.validateIsLastOperation(id); } @Override public List validateChangeProductOut(List list) { List snList = list.stream().map(ProductOutput::getOutBatchNo).collect(Collectors.toList()); List productOutputList = productOutputMapper.selectList(Wrappers.lambdaQuery() .in(ProductOutput::getOutBatchNo, snList).eq(ProductOutput::getState, ProductOutStateStringValues.CHANGESHIFT)); if (CollectionUtil.isNotEmpty(productOutputList)) { return list.stream().filter(s -> StringUtils.equals(s.getOutBatchNo(), productOutputList.get(0).getOutBatchNo())).collect(Collectors.toList()); } return null; } @Override public Boolean resetState(List ids) { List productMainList = baseMapper.selectList(Wrappers.lambdaQuery() .in(ProductMain::getId, ids) .eq(ProductMain::getState, ProductMainStateStringValues.PROCESSING)); productMainList.stream().forEach(a -> { a.setState(ProductMainStateStringValues.DRAFT); }); return this.updateBatchById(productMainList); } @Override public List getDraftProductOut(Long id) { return productOutputMapper.getDraftProductOut(id); } @Override public Boolean validateStepFinish(String outBatchNo) { Integer productOutCount = productOutputMapper.selectCount(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, outBatchNo)); if (productOutCount == 0) { return true; } List operationJoinStepList = operationJoinStepMapper.getOperationJoinStepBySn(outBatchNo); if (CollectionUtil.isNotEmpty(operationJoinStepList)) { Integer integer = productStepMapper.selectCount(Wrappers.lambdaQuery().eq(ProductStep::getStepId, operationJoinStepList.get(0).getTechnologyStepId()).eq(ProductStep::getSystemNo, outBatchNo)); if (integer == 0) { throw new RuntimeException("当前SN有工步流程未走完"); } } return Boolean.TRUE; } @Override public Boolean checkSn(StockDTO stockDTO) { if (StringUtils.isNotBlank(stockDTO.getPartBatchNo()) && !"*".equals(stockDTO.getPartBatchNo())) { List stockList = stockMapper.selectList(Wrappers.lambdaQuery().eq(Stock::getPartBatchNo, stockDTO.getPartBatchNo()).gt(Stock::getStockQuantity, 0)); if (CollectionUtil.isNotEmpty(stockList)) { if (!stockList.get(0).getPartId().equals(stockDTO.getPartId())) { throw new RuntimeException("零件号不一致"); } } List productOutputList = productOutputMapper.selectList(Wrappers.lambdaQuery().eq(ProductOutput::getOutBatchNo, stockDTO.getPartBatchNo()).eq(ProductOutput::getState, "01draft")); if (CollectionUtil.isNotEmpty(productOutputList)) { if (!productOutputList.get(0).getPartId().equals(stockDTO.getPartId())) { throw new RuntimeException("零件号不一致"); } } } return true; } /** * 判断工单是否是交班状态 * * @param productMainId * @return Boolean */ public Boolean judgeChangeshift(Long productMainId) { String state = productOutputMapper.judgeChangeshift(productMainId); if (ProductOutStateStringValues.CHANGESHIFT.equals(state)) { return true; } else { return false; } } public void updateLabelPrintTimes(List ids) { List outputList = productOutputMapper.selectList(Wrappers.lambdaQuery() .in(ProductOutput::getId, ids)); for (ProductOutput productOutput : outputList) { if (productOutput.getPrintNum() == null) { productOutput.setPrintNum(1L); } else { productOutput.setPrintNum(productOutput.getPrintNum() + 1); } } productOutputService.updateBatchById(outputList); } }