| | |
| | | package com.ruoyi.production.service.impl; |
| | | |
| | | import cn.hutool.core.lang.Assert; |
| | | import cn.hutool.extra.spring.SpringUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | |
| | | import com.ruoyi.basic.mapper.ProductModelMapper; |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.common.enums.AuditEnum; |
| | | import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | | import com.ruoyi.production.dto.ProductStructureDto; |
| | |
| | | import com.ruoyi.production.mapper.*; |
| | | import com.ruoyi.production.pojo.*; |
| | | import com.ruoyi.production.service.ProductionProductMainService; |
| | | import com.ruoyi.production.vo.ProductAuditVo; |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | | import com.ruoyi.project.system.mapper.SysUserMapper; |
| | | import com.ruoyi.quality.mapper.*; |
| | | import com.ruoyi.quality.pojo.*; |
| | | import com.ruoyi.quality.service.IQualityInspectService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.aop.framework.AopContext; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import com.ruoyi.production.mapper.ProductionProductMainMapper; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean addProductMain(ProductionProductMainDto dto) { |
| | | SysUser user = userMapper.selectUserById(dto.getUserId()); |
| | | ProductionProductMain productionProductMain = new ProductionProductMain(); |
| | |
| | | productionProductMain.setUserName(dto.getUserName()); |
| | | productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId()); |
| | | productionProductMain.setWorkOrderId(dto.getWorkOrderId()); |
| | | productionProductMain.setAuditUserId(dto.getAuditUserId()); |
| | | productionProductMain.setAuditUserName(dto.getAuditUserName()); |
| | | productionProductMain.setStatus(0); |
| | | productionProductMainMapper.insert(productionProductMain); |
| | | /*新增报工投入表*/ |
| | | List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId()); |
| | | if (productStructureDtos.size() == 0) { |
| | | if (productStructureDtos.isEmpty()) { |
| | | //如果该工序没有产品结构的投入品,那这个投入品和产出品是同一个 |
| | | ProductStructureDto productStructureDto = new ProductStructureDto(); |
| | | productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId()); |
| | |
| | | BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty()); |
| | | //只有合格数量>0才能增加相应数据 |
| | | if (productQty.compareTo(BigDecimal.ZERO) > 0) { |
| | | List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())); |
| | | /*更新工单和生产订单*/ |
| | | ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); |
| | | productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(productQty)); |
| | | if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) { |
| | | productWorkOrder.setActualStartTime(LocalDate.now());//实际开始时间 |
| | | } |
| | | if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0) { |
| | | productWorkOrder.setActualEndTime(LocalDate.now());//实际结束时间 |
| | | } |
| | | productWorkOrderMapper.updateById(productWorkOrder); |
| | | //生产订单 |
| | | ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); |
| | | if (ObjectUtils.isNull(productOrder.getStartTime())) { |
| | | productOrder.setStartTime(LocalDateTime.now());//开始时间 |
| | | } |
| | | if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) { |
| | | //如果是最后一道工序报工之后生产订单完成数量+ |
| | | productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(productQty)); |
| | | if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0) { |
| | | productOrder.setEndTime(LocalDateTime.now());//结束时间 |
| | | } |
| | | } |
| | | productOrderMapper.updateById(productOrder); |
| | | } |
| | | //如果报废数量>0,需要进入报废的库存 |
| | | if (ObjectUtils.isNotEmpty(dto.getScrapQty())) { |
| | | if (dto.getScrapQty().compareTo(BigDecimal.ZERO) > 0) { |
| | | stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId()); |
| | | } |
| | | } |
| | | //nextAddProductMain(productionProductOutput) // 由于需要审核,所以需要拆封下来 |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void auditProductMain(ProductAuditVo productAuditVo) { |
| | | ProductionProductMain productionProductMain = productionProductMainMapper.selectById(productAuditVo.getId()); |
| | | |
| | | // 当前审批人 要与当前登录人为同一人 |
| | | Assert.isTrue(SecurityUtils.getUserId().equals(productionProductMain.getAuditUserId()), "当前登录用户不是当前审批人"); |
| | | |
| | | |
| | | // 状态必须为待审核状态 |
| | | if (!Objects.equals(productionProductMain.getAuditStatus(), AuditEnum.NO_AUDIT.getCode())) { |
| | | throw new ServiceException("当前状态已审核,不能重复审核"); |
| | | } |
| | | |
| | | LambdaQueryWrapper<ProductionProductOutput> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()); |
| | | queryWrapper.last("limit 1"); |
| | | ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectOne(queryWrapper); |
| | | ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId()); |
| | | |
| | | |
| | | switch (productAuditVo.getAuditStatus()) { |
| | | case NO_AUDIT: |
| | | throw new ServiceException("修改审核状态失败,不能为未审核状态"); |
| | | case AUDIT_SUCCESS: |
| | | |
| | | Assert.isTrue(productionProductOutput != null, "没有找到对应的报工产出记录"); |
| | | ((ProductionProductMainService) AopContext.currentProxy()).nextAddProductMain(productionProductOutput); |
| | | break; |
| | | case AUDIT_FAIL: |
| | | // 减少 更新工单和生产订单 |
| | | ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId()); |
| | | ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); |
| | | |
| | | productWorkOrder.setCompleteQuantity( |
| | | productWorkOrder.getCompleteQuantity() |
| | | .subtract(productionProductOutput.getQuantity()) |
| | | .max(BigDecimal.ZERO) |
| | | ); |
| | | List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())); |
| | | |
| | | |
| | | if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) { |
| | | //如果是最后一道工序报工之后生产订单 需要扣除 |
| | | productOrder.setCompleteQuantity( |
| | | productOrder.getCompleteQuantity() |
| | | .subtract(productionProductOutput.getQuantity()) |
| | | .max(BigDecimal.ZERO) |
| | | ); |
| | | if (productOrder.getCompleteQuantity().compareTo(productionProductOutput.getQuantity()) > 0) { |
| | | productOrder.setEndTime(null); |
| | | } |
| | | productOrderMapper.updateById(productOrder); |
| | | } |
| | | |
| | | if (productWorkOrder.getCompleteQuantity().compareTo(productionProductOutput.getQuantity()) > 0) { |
| | | productWorkOrder.setActualEndTime(null); |
| | | } |
| | | |
| | | productWorkOrderMapper.updateById(productWorkOrder); |
| | | |
| | | break; |
| | | } |
| | | |
| | | // 修改状态 |
| | | ProductionProductMain updateDate = new ProductionProductMain(); |
| | | updateDate.setId(productionProductMain.getId()); |
| | | updateDate.setAuditStatus(productAuditVo.getAuditStatus().getCode()); |
| | | updateDate.setSureAuditUserId(SecurityUtils.getUserId()); |
| | | updateDate.setSureAuditUserName(SecurityUtils.getUsername()); |
| | | updateDate.setAuditTime(LocalDateTime.now()); |
| | | updateDate.setAuditOpinion(productAuditVo.getAuditOpinion()); |
| | | productionProductMainMapper.updateById(updateDate); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void nextAddProductMain(@NotNull ProductionProductOutput productionProductOutput){ |
| | | //合格数量=报工数量-报废数量 |
| | | ProductionProductMain productionProductMain = productionProductMainMapper.selectById(productionProductOutput.getProductMainId()); |
| | | BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty()); |
| | | ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId()); |
| | | ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId()); |
| | | //工艺路线中当前工序对应的产出规格型号 |
| | | ProductModel productModel = productModelMapper.selectById(productProcessRouteItem.getProductModelId()); |
| | | SysUser user = userMapper.selectUserById(SecurityUtils.getUserId()); |
| | | |
| | | //只有合格数量>0才能增加相应数据 |
| | | if (productQty.compareTo(BigDecimal.ZERO) > 0) { |
| | | /*新增质检*/ |
| | | List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())); |
| | | if (productProcessRouteItem.getIsQuality()) { |
| | |
| | | qualityInspect.setProductModelId(productModel.getId()); |
| | | qualityInspectMapper.insert(qualityInspect); |
| | | List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process); |
| | | if (qualityTestStandard.size() > 0) { |
| | | if (!qualityTestStandard.isEmpty()) { |
| | | qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId()); |
| | | qualityInspectMapper.updateById(qualityInspect); |
| | | qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery() |
| | |
| | | //直接入库 |
| | | stockUtils.addStock(productProcessRouteItem.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId()); |
| | | } |
| | | /*更新工单和生产订单*/ |
| | | ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); |
| | | productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(productQty)); |
| | | if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) { |
| | | productWorkOrder.setActualStartTime(LocalDate.now());//实际开始时间 |
| | | } |
| | | if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0) { |
| | | productWorkOrder.setActualEndTime(LocalDate.now());//实际结束时间 |
| | | } |
| | | productWorkOrderMapper.updateById(productWorkOrder); |
| | | //生产订单 |
| | | ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); |
| | | if (ObjectUtils.isNull(productOrder.getStartTime())) { |
| | | productOrder.setStartTime(LocalDateTime.now());//开始时间 |
| | | } |
| | | if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) { |
| | | //如果是最后一道工序报工之后生产订单完成数量+ |
| | | productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(productQty)); |
| | | if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0) { |
| | | productOrder.setEndTime(LocalDateTime.now());//结束时间 |
| | | } |
| | | } |
| | | productOrderMapper.updateById(productOrder); |
| | | /*添加生产核算*/ |
| | | |
| | | /*添加生产核算 区分工序是计件还是计时*/ |
| | | BigDecimal workHours = (productProcess.getType() == 1) |
| | | ? productProcess.getSalaryQuota().multiply(productQty) |
| | | : productProcess.getSalaryQuota(); |
| | | |
| | | SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder() |
| | | .productMainId(productionProductMain.getId()) |
| | | .schedulingUserId(user.getUserId()) |
| | | .schedulingUserName(user.getNickName()) |
| | | .finishedNum(productQty) |
| | | .workHours(productProcess.getSalaryQuota()) |
| | | .workHours(workHours) |
| | | .process(productProcess.getName()) |
| | | .schedulingDate(LocalDate.now()) |
| | | .tenantId(dto.getTenantId()) |
| | | .tenantId(productionProductOutput.getTenantId()) |
| | | .build(); |
| | | salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting); |
| | | } |
| | | //如果报废数量>0,需要进入报废的库存 |
| | | if (ObjectUtils.isNotEmpty(dto.getScrapQty())) { |
| | | if (dto.getScrapQty().compareTo(BigDecimal.ZERO) > 0) { |
| | | stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId()); |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | @Override |