src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -103,6 +103,18 @@ stockInventoryService.addstockInventory(stockInventoryDto); } public void addStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String processCategory, String voltage) { StockInventoryDto stockInventoryDto = new StockInventoryDto(); stockInventoryDto.setRecordId(recordId); stockInventoryDto.setRecordType(String.valueOf(recordType)); stockInventoryDto.setQualitity(quantity); stockInventoryDto.setProductModelId(productModelId); stockInventoryDto.setProcessCategory(processCategory); stockInventoryDto.setVoltage(voltage); stockInventoryService.addstockInventory(stockInventoryDto); } /** * åæ ¼å ¥åºï¼ä¸å®¡æ ¸ï¼ * @@ -120,6 +132,18 @@ stockInventoryService.addstockInventoryNoReview(stockInventoryDto); } public void addStockNoReview(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String processCategory, String voltage) { StockInventoryDto stockInventoryDto = new StockInventoryDto(); stockInventoryDto.setRecordId(recordId); stockInventoryDto.setRecordType(String.valueOf(recordType)); stockInventoryDto.setQualitity(quantity); stockInventoryDto.setProductModelId(productModelId); stockInventoryDto.setProcessCategory(processCategory); stockInventoryDto.setVoltage(voltage); stockInventoryService.addstockInventoryNoReview(stockInventoryDto); } /** * åæ ¼åºåº * src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -19,14 +19,12 @@ IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, @Param("c") ProductionProductMainDto productionProductMainDto); /** * æ ¹æ®å·¥åIDæ¹éå é¤çäº§ä¸»è¡¨æ°æ® * æ ¹æ®å·¥å ID æ¹éå 餿¥å·¥ä¸»è¡¨æ°æ®ã */ int deleteByWorkOrderIds(@Param("workOrderIds") List<Long> workOrderIds); /** * æ ¹æ®æ¥å·¥idæ¥è¯¢ç产订å * @param productMainId * @return * æ ¹æ®æ¥å·¥ ID æ¥è¯¢ç产订åã */ ProductOrder getOrderByMainId(@Param("productMainId") Long productMainId); @@ -37,10 +35,7 @@ List<ProductionProductMainDto> getByProductWorkOrderId(Long productWorkOrderId); /** * æ£æ¥ä¹åçå·¥åºæ¯å¦æè¢«é离çä¸åæ ¼è®°å½ * @param productRouteId å½åå·¥åºçè·¯ç±ID * @param currentDragSort å½åå·¥åºçæåº * @return æ¯å¦æé离çä¸åæ ¼è®°å½ * æ ¡éªåä¸ç产订åä¸çä¸ä¸éå·¥åºæ¯å¦å·²ç»æ¥å·¥ã */ boolean checkPreviousProcessReported(@Param("productRouteId") Long productRouteId, @Param("currentDragSort") Integer currentDragSort); boolean checkPreviousProcessReported(@Param("workOrderId") Long workOrderId, @Param("currentDragSort") Integer currentDragSort); } src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -69,7 +69,7 @@ } else { // ä¸ä¸ä¸ªå·¥åºæ¯å¦å·²æ¥å·¥ boolean isPreviousReported = productionProductMainMapper.checkPreviousProcessReported( record.getProductRouteId(), record.getId(), currentDragSort ); record.setIsCanReport(isPreviousReported); @@ -94,7 +94,13 @@ } // æ£æ¥ä¹åçå·¥åºæ¯å¦æè¢«é离çä¸åæ ¼è®°å½ List<QualityUnqualified> unqualifiedList = qualityUnqualifiedMapper.selectUnqualifiedByProcessNames(previousProcessNames); List<QualityUnqualified> unqualifiedList = Collections.emptyList(); if (CollectionUtils.isNotEmpty(previousProcessNames)) { unqualifiedList = qualityUnqualifiedMapper.selectUnqualifiedByProductOrderAndProcessNames( record.getProductOrderId(), previousProcessNames ); } if (CollectionUtils.isNotEmpty(unqualifiedList)) { record.setIsCanReport(false); } @@ -231,4 +237,4 @@ } return productWorkOrderDtos; } } } src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -17,6 +17,7 @@ import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.production.dto.ProductStructureDto; @@ -30,6 +31,7 @@ import com.ruoyi.quality.mapper.*; import com.ruoyi.quality.pojo.*; import com.ruoyi.quality.service.IQualityInspectService; import com.ruoyi.stock.support.FinishedProductStockDimensionResolver; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -48,44 +50,32 @@ @Transactional(rollbackFor = Exception.class) public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService { private static final String PROCESS_VOLTAGE_SORT = "çµååé"; private static final String PROCESS_OPTICAL_INSPECTION = "å æ£å¤è§"; private static final String PROCESS_PACKAGING = "å è£ "; private static final Object PRODUCT_MAIN_NO_LOCK = new Object(); private IQualityInspectService qualityInspectService; private ProductionProductMainMapper productionProductMainMapper; private ProductWorkOrderMapper productWorkOrderMapper; private ProductProcessRouteItemMapper productProcessRouteItemMapper; private SysUserMapper userMapper; private ProductionProductOutputMapper productionProductOutputMapper; private ProductModelMapper productModelMapper; private QualityInspectMapper qualityInspectMapper; private QualityUnqualifiedMapper qualityUnqualifiedMapper; private ProductProcessMapper productProcessMapper; private ProductProcessRouteMapper productProcessRouteMapper; private ProductMapper productMapper; private QualityTestStandardParamMapper qualityTestStandardParamMapper; private QualityTestStandardMapper qualityTestStandardMapper; private QualityInspectParamMapper qualityInspectParamMapper; private ProductStructureMapper productStructureMapper; private ProductionProductInputMapper productionProductInputMapper; private ProductOrderMapper productOrderMapper; private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper; private StockUtils stockUtils; private FinishedProductStockDimensionResolver finishedProductStockDimensionResolver; private ISysNoticeService sysNoticeService; @Override @@ -93,122 +83,246 @@ return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto); } // æ°å¢æ¥å·¥ï¼å¹¶æç §æ¥å·¥ä¸»æµç¨å¤çæå ¥æ£åºã产åºãè´¨æ£ãå ¥åºãå·¥å订åè¿åº¦åæ ¸ç®æ°æ® @Override public Boolean addProductMain(ProductionProductMainDto dto) { SysUser user = userMapper.selectUserById(dto.getUserId()); ProductionProductMain productionProductMain = new ProductionProductMain(); //å½åå·¥èºè·¯çº¿å¯¹åºçå·¥åºè¯¦æ ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId()); if (productProcessRouteItem == null) { throw new RuntimeException("å·¥èºè·¯çº¿é¡¹ä¸åå¨"); // ç¬¬ä¸æ¥ï¼å æ ¡éªæ¥å·¥å ¥åï¼é¿å 空å¼åéæ³æ°éè¿å ¥åç»æµç¨ if (dto == null) { throw new ServiceException("æ¥å·¥åæ°ä¸è½ä¸ºç©º"); } // æ¯å¦è½æ¥å·¥ï¼ 1. 第ä¸ä¸ªå·¥åºè½æ¥å·¥ 2. ä¸ä¸ä¸ªå·¥åºå·²æ¥å·¥ 3. ä¹åçå·¥åºæªè¢«é离 //æ£æ¥ä¸ä¸ä¸ªå·¥åºæ¯å¦å·²æ¥å·¥ if (dto.getProductProcessRouteItemId() == null) { throw new ServiceException("å·¥èºè·¯çº¿å·¥åºé¡¹ä¸è½ä¸ºç©º"); } if (dto.getWorkOrderId() == null) { throw new ServiceException("ç产工åä¸è½ä¸ºç©º"); } BigDecimal reportQty = dto.getQuantity(); BigDecimal scrapQty = dto.getScrapQty() == null ? BigDecimal.ZERO : dto.getScrapQty(); if (reportQty == null || reportQty.compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("æ¥å·¥æ°éå¿ é¡»å¤§äº0"); } if (scrapQty.compareTo(BigDecimal.ZERO) < 0) { throw new ServiceException("æ¥åºæ°éä¸è½å°äº0"); } if (scrapQty.compareTo(reportQty) > 0) { throw new ServiceException("æ¥åºæ°éä¸è½å¤§äºæ¥å·¥æ°é"); } // ç¬¬äºæ¥ï¼å è½½å½åå·¥åºãå·¥åãå·¥èºè·¯çº¿åè®¢åæ°æ®ï¼å¹¶æ ¡éªåºç¡å ³èå ³ç³» ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId()); if (productProcessRouteItem == null) { throw new ServiceException("å·¥èºè·¯çº¿å·¥åºé¡¹ä¸åå¨"); } ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId()); if (productProcess == null) { throw new ServiceException("å½åå·¥åºä¸åå¨"); } ProductModel productModel = productModelMapper.selectById(productProcessRouteItem.getProductModelId()); if (productModel == null) { throw new ServiceException("å½åå·¥åºå¯¹åºç产ååå·ä¸åå¨"); } ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectById(productProcessRouteItem.getProductRouteId()); if (productProcessRoute == null) { throw new ServiceException("å·¥èºè·¯çº¿ä¸åå¨"); } ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); if (productWorkOrder == null) { throw new ServiceException("ç产工åä¸åå¨"); } if (!Objects.equals(productWorkOrder.getProductProcessRouteItemId(), productProcessRouteItem.getId())) { throw new ServiceException("ç产工åä¸å½åå·¥åºä¸å¹é "); } ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); if (productOrder == null) { throw new ServiceException("ç产订åä¸åå¨"); } // ç¬¬ä¸æ¥ï¼æ ¡éªå·¥åºæµè½¬é»è¾ï¼å¿ é¡»æ¯åä¸è®¢åçä¸ä¸éå·¥åºå·²æ¥å·¥ä¸ååºæ æªè§£é¤éç¦»è®°å½ Integer currentDragSort = productProcessRouteItem.getDragSort(); if (currentDragSort != null && currentDragSort > 1) { boolean isPreviousReported = productionProductMainMapper.checkPreviousProcessReported( productProcessRouteItem.getProductRouteId(), productWorkOrder.getId(), currentDragSort ); if (!isPreviousReported) { throw new RuntimeException("ä¸ä¸ä¸ªå·¥åºå°æªæ¥å·¥ï¼ä¸è½è¿è¡å½åå·¥åºæ¥å·¥"); throw new ServiceException("ä¸ä¸éå·¥åºå°æªæ¥å·¥ï¼å½åå·¥åºä¸è½æ¥å·¥"); } // æ¥è¯¢ææä¹åçå·¥åºï¼æåºå·å°äºå½åå·¥åºï¼ ProductProcessRouteItem previousRouteItem = productProcessRouteItemMapper.selectOne( Wrappers.<ProductProcessRouteItem>lambdaQuery() .eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()) .eq(ProductProcessRouteItem::getDragSort, currentDragSort - 1) ); if (previousRouteItem == null) { throw new ServiceException("ä¸ä¸éå·¥åºä¸åå¨"); } ProductWorkOrder previousWorkOrder = productWorkOrderMapper.selectOne( Wrappers.<ProductWorkOrder>lambdaQuery() .eq(ProductWorkOrder::getProductOrderId, productOrder.getId()) .eq(ProductWorkOrder::getProductProcessRouteItemId, previousRouteItem.getId()) ); if (previousWorkOrder == null) { throw new ServiceException("ä¸ä¸éå·¥åºå·¥åä¸åå¨"); } BigDecimal currentReportedQty = BigDecimal.ZERO; List<ProductionProductMain> currentMainList = productionProductMainMapper.selectList( Wrappers.<ProductionProductMain>lambdaQuery() .eq(ProductionProductMain::getWorkOrderId, productWorkOrder.getId()) ); if (CollectionUtils.isNotEmpty(currentMainList)) { List<Long> currentMainIds = currentMainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); List<ProductionProductOutput> currentOutputList = productionProductOutputMapper.selectList( Wrappers.<ProductionProductOutput>lambdaQuery() .in(ProductionProductOutput::getProductMainId, currentMainIds) ); currentReportedQty = currentOutputList.stream() .map(ProductionProductOutput::getQuantity) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add); } BigDecimal previousCompleteQty = previousWorkOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : previousWorkOrder.getCompleteQuantity(); if (currentReportedQty.add(reportQty).compareTo(previousCompleteQty) > 0) { throw new ServiceException("æ¬æ¬¡æ¥å·¥æ°éè¶ è¿ä¸éå·¥åºå¯æµè½¬æ°é"); } List<ProductProcessRouteItem> previousItems = productProcessRouteItemMapper.selectList( Wrappers.<ProductProcessRouteItem>lambdaQuery() .eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()) .lt(ProductProcessRouteItem::getDragSort, currentDragSort) ); if (CollectionUtils.isNotEmpty(previousItems)) { // æåä¹åå·¥åºçåç§°å表 List<String> previousProcessNames = new ArrayList<>(); for (ProductProcessRouteItem item : previousItems) { ProductProcess process = productProcessMapper.selectById(item.getProcessId()); if (process != null) { previousProcessNames.add(process.getName()); if (process != null && StringUtils.isNotBlank(process.getName())) { previousProcessNames.add(process.getName().trim()); } } // æ£æ¥ä¹åçå·¥åºæ¯å¦æè¢«é离çä¸åæ ¼è®°å½ List<QualityUnqualified> unqualifiedList = qualityUnqualifiedMapper.selectUnqualifiedByProcessNames(previousProcessNames); if (CollectionUtils.isNotEmpty(unqualifiedList)) { throw new RuntimeException("ä¹åçå·¥åºå·²è¢«é离ï¼ä¸è½è¿è¡å½åå·¥åºæ¥å·¥"); if (CollectionUtils.isNotEmpty(previousProcessNames)) { List<QualityUnqualified> unqualifiedList = qualityUnqualifiedMapper.selectUnqualifiedByProductOrderAndProcessNames(productOrder.getId(), previousProcessNames); if (CollectionUtils.isNotEmpty(unqualifiedList)) { throw new ServiceException("ååºå·¥åºåå¨é离记å½ï¼å½åå·¥åºä¸è½æ¥å·¥"); } } } } //å½åå ·ä½å·¥åº ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId()); //å·¥èºè·¯çº¿ä¸å½åå·¥åºå¯¹åºç产åºè§æ ¼åå· ProductModel productModel = productModelMapper.selectById(productProcessRouteItem.getProductModelId()); //æ¥è¯¢è¯¥ç产订å对åºçbom ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectById(productProcessRouteItem.getProductRouteId()); /*æ°å¢æ¥å·¥ä¸»è¡¨*/ //æ¥è¯¢æå¤§æ¥å·¥ç¼å· String datePrefix = "BG" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd")); QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>(); queryWrapper.select("MAX(product_no) as maxNo") .likeRight("product_no", datePrefix); List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper); int sequenceNumber = 1; if (resultList != null && !resultList.isEmpty()) { Map<String, Object> result = resultList.get(0); if (result != null) { Object maxNoObj = result.get("maxNo"); if (maxNoObj != null) { String lastNo = maxNoObj.toString(); // ç¬¬åæ¥ï¼æ§å¶å½å工忻æ¥å·¥éä¸è½è¶ è¿è®¡åé BigDecimal currentWorkOrderReportedQty = BigDecimal.ZERO; List<ProductionProductMain> workOrderMainList = productionProductMainMapper.selectList( Wrappers.<ProductionProductMain>lambdaQuery() .eq(ProductionProductMain::getWorkOrderId, productWorkOrder.getId()) ); if (CollectionUtils.isNotEmpty(workOrderMainList)) { List<Long> workOrderMainIds = workOrderMainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); List<ProductionProductOutput> workOrderOutputList = productionProductOutputMapper.selectList( Wrappers.<ProductionProductOutput>lambdaQuery() .in(ProductionProductOutput::getProductMainId, workOrderMainIds) ); currentWorkOrderReportedQty = workOrderOutputList.stream() .map(ProductionProductOutput::getQuantity) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add); } if (productWorkOrder.getPlanQuantity() != null && currentWorkOrderReportedQty.add(reportQty).compareTo(productWorkOrder.getPlanQuantity()) > 0) { throw new ServiceException("æ¬æ¬¡æ¥å·¥æ°éè¶ è¿å·¥å坿¥æ°é"); } // ç¬¬äºæ¥ï¼çææ¥å·¥åå·å¹¶ç¡®å®æ¥å·¥äººä¿¡æ¯ String productNo; synchronized (PRODUCT_MAIN_NO_LOCK) { String datePrefix = "BG" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd")); QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>(); queryWrapper.select("MAX(product_no) as maxNo") .likeRight("product_no", datePrefix); List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper); int sequenceNumber = 1; if (CollectionUtils.isNotEmpty(resultList)) { Map<String, Object> result = resultList.get(0); if (result != null && result.get("maxNo") != null) { String lastNo = result.get("maxNo").toString(); if (lastNo.startsWith(datePrefix)) { try { String seqStr = lastNo.substring(datePrefix.length()); sequenceNumber = Integer.parseInt(seqStr) + 1; sequenceNumber = Integer.parseInt(lastNo.substring(datePrefix.length())) + 1; } catch (NumberFormatException e) { sequenceNumber = 1; } } } } productNo = String.format("%s%03d", datePrefix, sequenceNumber); } String productNo = String.format("%s%03d", datePrefix, sequenceNumber); productionProductMain.setProductNo(productNo); Long userId = dto.getUserId(); String userName = dto.getUserName(); if (userId == null) { userId = SecurityUtils.getLoginUser().getUserId(); userName = SecurityUtils.getLoginUser().getNickName(); } else if (StringUtils.isBlank(userName)) { SysUser user = userMapper.selectUserById(userId); userName = user == null ? null : user.getNickName(); } // ç¬¬å æ¥ï¼å åæ¥å·¥ä¸»è¡¨ ProductionProductMain productionProductMain = new ProductionProductMain(); productionProductMain.setProductNo(productNo); productionProductMain.setUserId(userId); productionProductMain.setUserName(userName); productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId()); productionProductMain.setWorkOrderId(dto.getWorkOrderId()); productionProductMain.setStatus(0); productionProductMainMapper.insert(productionProductMain); /*æ°å¢æ¥å·¥æå ¥è¡¨*/ List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId()); if (productStructureDtos.isEmpty()) { //å¦æè¯¥å·¥åºæ²¡æäº§åç»æçæå ¥å,é£è¿ä¸ªæå ¥åå产åºåæ¯åä¸ä¸ª // ç¬¬ä¸æ¥ï¼æ ¹æ® BOM çææå ¥è®°å½å¹¶æ£ååæåºå List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId()); if (CollectionUtils.isEmpty(productStructureDtos)) { ProductStructureDto productStructureDto = new ProductStructureDto(); productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId()); productStructureDto.setUnitQuantity(BigDecimal.ONE); productStructureDtos.add(productStructureDto); } Set<Long> parentIds = productStructureDtos.stream() .map(ProductStructureDto::getParentId) .filter(Objects::nonNull) .collect(Collectors.toSet()); Map<Long, ProductStructureDto> parentMap = new HashMap<>(); if (!parentIds.isEmpty()) { if (CollectionUtils.isNotEmpty(parentIds)) { parentMap = productStructureMapper.selectByIds(parentIds) .stream() .collect(Collectors.toMap( ProductStructureDto::getId, Function.identity() )); .collect(Collectors.toMap(ProductStructureDto::getId, Function.identity(), (a, b) -> a)); } for (ProductStructureDto productStructureDto : productStructureDtos) { ProductionProductInput productionProductInput = new ProductionProductInput(); productionProductInput.setProductModelId(productStructureDto.getProductModelId()); // productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity())); if (productStructureDto.getProductModelId() == null) { throw new ServiceException("æå ¥ç©æäº§ååå·ä¸è½ä¸ºç©º"); } BigDecimal childQty = productStructureDto.getUnitQuantity(); if (childQty == null || childQty.compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("æå ¥ç©æç¨éå¿ é¡»å¤§äº0"); } BigDecimal parentQty = BigDecimal.ONE; if (productStructureDto.getParentId() != null) { ProductStructureDto parent = parentMap.get(productStructureDto.getParentId()); @@ -217,150 +331,317 @@ } } // æ ¸å¿è®¡ç® BigDecimal needQty = childQty.divide(parentQty, 6, RoundingMode.HALF_UP).multiply(dto.getQuantity()); if (parentQty == null || parentQty.compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("ç¶çº§ç©æç¨éå¿ é¡»å¤§äº0"); } BigDecimal needQty = childQty .divide(parentQty, 6, RoundingMode.HALF_UP) .multiply(reportQty); ProductionProductInput productionProductInput = new ProductionProductInput(); productionProductInput.setProductModelId(productStructureDto.getProductModelId()); productionProductInput.setQuantity(needQty); productionProductInput.setProductMainId(productionProductMain.getId()); productionProductInputMapper.insert(productionProductInput); stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId(), null); stockUtils.substractStock( productStructureDto.getProductModelId(), needQty, StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId(), null ); } /*æ°å¢æ¥å·¥äº§åºè¡¨*/ // ç¬¬å «æ¥ï¼å产åºè®°å½å¹¶è®¡ç®æ¬æ¬¡åæ ¼æ°é ProductionProductOutput productionProductOutput = new ProductionProductOutput(); productionProductOutput.setProductMainId(productionProductMain.getId()); productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId()); productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO); productionProductOutput.setScrapQty(dto.getScrapQty() != null ? dto.getScrapQty() : BigDecimal.ZERO); productionProductOutput.setOtherData(dto.getOtherData() != null ? dto.getOtherData() : ""); productionProductOutput.setQuantity(reportQty); productionProductOutput.setScrapQty(scrapQty); productionProductOutput.setOtherData(dto.getOtherData() == null ? "" : dto.getOtherData()); productionProductOutputMapper.insert(productionProductOutput); ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); BigDecimal qualifiedQty = reportQty.subtract(scrapQty); //åæ ¼æ°é=æ¥å·¥æ°é-æ¥åºæ°é BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty()); List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())); //åªæåæ ¼æ°é>0æè½å¢å ç¸åºæ°æ® if (productQty.compareTo(BigDecimal.ZERO) > 0) { /*æ°å¢è´¨æ£*/ if (productProcessRouteItem.getIsQuality()) { //对åºçè¿ç¨æ£æè åºåæ£ List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList( Wrappers.<ProductProcessRouteItem>lambdaQuery() .eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()) ); Integer maxDragSort = productProcessRouteItems.stream() .map(ProductProcessRouteItem::getDragSort) .filter(Objects::nonNull) .max(Integer::compareTo) .orElse(null); boolean isRouteLastProcess = Objects.equals(productProcessRouteItem.getDragSort(), maxDragSort); ReportStockRule reportStockRule = resolveReportStockRule(productProcessRouteItem, productProcess, productProcessRouteItems); // ç¬¬ä¹æ¥ï¼å¦ææåæ ¼æ°éï¼åæ ¹æ®æ¯å¦è´¨æ£å³å®èµ°è´¨æ£æç´æ¥å ¥åº if (qualifiedQty.compareTo(BigDecimal.ZERO) > 0) { if (Boolean.TRUE.equals(productProcessRouteItem.getIsQuality())) { Product product = productMapper.selectById(productModel.getProductId()); if (product == null) { throw new ServiceException("è´¨æ£äº§åä¸åå¨"); } int inspectType = 1; String process = productProcess.getName();//å·¥åº if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) { //æåä¸éå·¥åºçæåºåæ£ String process = productProcess.getName(); if (reportStockRule.finishedGoodsStockIn) { inspectType = 2; process = null; } Product product = productMapper.selectById(productModel.getProductId()); QualityInspect qualityInspect = new QualityInspect(); qualityInspect.setProductId(product.getId()); qualityInspect.setProductName(product.getProductName()); qualityInspect.setModel(productModel.getModel()); qualityInspect.setUnit(productModel.getUnit()); qualityInspect.setQuantity(productQty); qualityInspect.setQuantity(reportQty); qualityInspect.setProcess(process); qualityInspect.setInspectState(0); qualityInspect.setInspectType(inspectType); qualityInspect.setDefectiveQuantity(BigDecimal.ZERO); qualityInspect.setDefectiveQuantity(scrapQty); qualityInspect.setProductMainId(productionProductMain.getId()); qualityInspect.setProductModelId(productModel.getId()); qualityInspectMapper.insert(qualityInspect); List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process); if (qualityTestStandard.size() > 0) { qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId()); List<QualityTestStandard> qualityTestStandardList = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process); if (CollectionUtils.isNotEmpty(qualityTestStandardList)) { QualityTestStandard qualityTestStandard = qualityTestStandardList.get(0); qualityInspect.setTestStandardId(qualityTestStandard.getId()); qualityInspectMapper.updateById(qualityInspect); qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery() .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId()))//é»è®¤è·åææ°ç .forEach(qualityTestStandardParam -> { QualityInspectParam param = new QualityInspectParam(); BeanUtils.copyProperties(qualityTestStandardParam, param); param.setId(null); param.setInspectId(qualityInspect.getId()); qualityInspectParamMapper.insert(param); }); qualityTestStandardParamMapper.selectList( Wrappers.<QualityTestStandardParam>lambdaQuery() .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.getId()) ).forEach(qualityTestStandardParam -> { QualityInspectParam param = new QualityInspectParam(); BeanUtils.copyProperties(qualityTestStandardParam, param); param.setId(null); param.setInspectId(qualityInspect.getId()); qualityInspectParamMapper.insert(param); }); } }else { //ç´æ¥å ¥åº //æåä¸éå·¥åºä¸ºæå if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) { //æåå®¡æ ¸ stockUtils.addStock(productProcessRouteItem.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId()); }else { //åæåä¸å®¡æ ¸ stockUtils.addStockNoReview(productProcessRouteItem.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId()); } else if (reportStockRule.createStockIn) { //æåå ¥åºéè¦çµåï¼å·¥åºç±»å«ï¼éï¼é¶ï¼ if (reportStockRule.finishedGoodsStockIn) { String processCategory = finishedProductStockDimensionResolver.resolveProcessCategory(productionProductMain.getId()); String voltage = finishedProductStockDimensionResolver.resolveVoltage(productionProductMain.getId()); stockUtils.addStock( productProcessRouteItem.getProductModelId(), qualifiedQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId(), processCategory, voltage ); } else { stockUtils.addStockNoReview( productProcessRouteItem.getProductModelId(), qualifiedQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId() ); } } /*æ´æ°å·¥ååç产订å*/ productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(productQty)); // ç¬¬åæ¥ï¼æ´æ°å·¥åã订å宿è¿åº¦åè®¡ä»¶æ ¸ç®æ°æ® BigDecimal workOrderCompleteQuantity = productWorkOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productWorkOrder.getCompleteQuantity(); productWorkOrder.setCompleteQuantity(workOrderCompleteQuantity.add(qualifiedQty)); if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) { productWorkOrder.setActualStartTime(LocalDate.now());//å®é å¼å§æ¶é´ productWorkOrder.setActualStartTime(LocalDate.now()); } if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0) { productWorkOrder.setActualEndTime(LocalDate.now());//å®é ç»ææ¶é´ if (productWorkOrder.getPlanQuantity() != null && productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) >= 0) { productWorkOrder.setActualEndTime(LocalDate.now()); } productWorkOrderMapper.updateById(productWorkOrder); //ç产订å if (ObjectUtils.isNull(productOrder.getStartTime())) { productOrder.setStartTime(LocalDateTime.now());//å¼å§æ¶é´ 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());//ç»ææ¶é´ if (isRouteLastProcess) { BigDecimal orderCompleteQuantity = productOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productOrder.getCompleteQuantity(); productOrder.setCompleteQuantity(orderCompleteQuantity.add(qualifiedQty)); if (productOrder.getQuantity() != null && productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) >= 0) { productOrder.setEndTime(LocalDateTime.now()); } } productOrderMapper.updateById(productOrder); /*æ·»å çäº§æ ¸ç®*/ SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder() .productMainId(productionProductMain.getId()) .schedulingUserId(userId) .schedulingUserName(userName) .finishedNum(productQty) .workHours(productProcess.getSalaryQuota()) .process(productProcess.getName()) .schedulingDate(LocalDate.now()) .tenantId(dto.getTenantId()) .build(); SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder() .productMainId(productionProductMain.getId()) .schedulingUserId(userId) .schedulingUserName(userName) .finishedNum(qualifiedQty) .workHours(productProcess.getSalaryQuota()) .process(productProcess.getName()) .schedulingDate(LocalDate.now()) .tenantId(dto.getTenantId()) .build(); salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting); } //妿æ¥åºæ°é>0,éè¦è¿å ¥æ¥åºçåºå if (ObjectUtils.isNotEmpty(dto.getScrapQty())) { if (dto.getScrapQty().compareTo(BigDecimal.ZERO) > 0) { if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()){ stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId()); }else { stockUtils.addUnStockNoReview(productModel.getId(), dto.getScrapQty(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId()); } } } // 第å䏿¥ï¼ç»ä¸å¤çæ¥åºæ°éå ¥ä¸åæ ¼åºåï¼é¿å å¨ä¸»æµç¨ä¸éå¤å ¥åº handleScrapStock(productModel.getId(), scrapQty, isRouteLastProcess, productionProductMain.getId()); return true; } // 夿å½åæ¥å·¥æ¯å¦éè¦å ¥åºï¼ä»¥åæ¯å¦ææåå ¥åºå¤ç private ReportStockRule resolveReportStockRule(ProductProcessRouteItem currentRouteItem, ProductProcess currentProcess, List<ProductProcessRouteItem> routeItems) { Integer maxDragSort = CollectionUtils.isEmpty(routeItems) ? null : routeItems.stream() .map(ProductProcessRouteItem::getDragSort) .filter(Objects::nonNull) .max(Integer::compareTo) .orElse(null); boolean isRouteLastProcess = Objects.equals(currentRouteItem.getDragSort(), maxDragSort); String currentProcessName = currentProcess == null || currentProcess.getName() == null ? "" : currentProcess.getName().trim(); if (PROCESS_VOLTAGE_SORT.equals(currentProcessName)) { return new ReportStockRule(false, false); } Set<Long> processIds = CollectionUtils.isEmpty(routeItems) ? Collections.emptySet() : routeItems.stream() .map(ProductProcessRouteItem::getProcessId) .filter(Objects::nonNull) .collect(Collectors.toSet()); Map<Long, String> processNameMap = new HashMap<>(); if (CollectionUtils.isNotEmpty(processIds)) { processNameMap = productProcessMapper.selectBatchIds(processIds) .stream() .collect(Collectors.toMap( ProductProcess::getId, process -> process.getName() == null ? "" : process.getName().trim(), (a, b) -> a )); } Set<String> routeProcessNames = CollectionUtils.isEmpty(routeItems) ? Collections.emptySet() : routeItems.stream() .map(ProductProcessRouteItem::getProcessId) .map(processNameMap::get) .filter(StringUtils::isNotBlank) .collect(Collectors.toSet()); boolean hasVoltageSort = routeProcessNames.contains(PROCESS_VOLTAGE_SORT); boolean hasOpticalInspection = routeProcessNames.contains(PROCESS_OPTICAL_INSPECTION); boolean hasPackaging = routeProcessNames.contains(PROCESS_PACKAGING); if (hasPackaging && PROCESS_PACKAGING.equals(currentProcessName)) { return new ReportStockRule(true, true); } if (hasPackaging && PROCESS_OPTICAL_INSPECTION.equals(currentProcessName)) { return new ReportStockRule(false, false); } if (!hasPackaging && hasVoltageSort && hasOpticalInspection && PROCESS_OPTICAL_INSPECTION.equals(currentProcessName)) { return new ReportStockRule(true, true); } return new ReportStockRule(true, isRouteLastProcess); } // ç»ä¸å¤çæ¥åºæ°éå ¥ä¸åæ ¼åºåï¼é¿å éå¤å ¥åº private void handleScrapStock(Long productModelId, BigDecimal scrapQty, boolean isRouteLastProcess, Long productMainId) { if (productModelId == null) { throw new ServiceException("æ¥åºäº§ååå·ä¸è½ä¸ºç©º"); } if (scrapQty == null || scrapQty.compareTo(BigDecimal.ZERO) <= 0) { return; } if (isRouteLastProcess) { stockUtils.addUnStock( productModelId, scrapQty, StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productMainId ); } else { stockUtils.addUnStockNoReview( productModelId, scrapQty, StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productMainId ); } } // 忬¡æ¥å·¥å¯¹åºçå ¥åºè§å private static final class ReportStockRule { private final boolean createStockIn; private final boolean finishedGoodsStockIn; private ReportStockRule(boolean createStockIn, boolean finishedGoodsStockIn) { this.createStockIn = createStockIn; this.finishedGoodsStockIn = finishedGoodsStockIn; } } @Override public Boolean removeProductMain(Long id) { //å¤æè¯¥æ¡æ¥å·¥æ¯å¦ä¸åæ ¼å¤ç,妿ä¸åæ ¼å¤çäºï¼åä¸å 许å é¤ List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(Wrappers.<QualityInspect>lambdaQuery().eq(QualityInspect::getProductMainId, id)); if (qualityInspects.size() > 0){ List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList(Wrappers.<QualityUnqualified>lambdaQuery() .in(QualityUnqualified::getInspectId, qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList()))); if (qualityUnqualifieds.size() > 0 && qualityUnqualifieds.get(0).getInspectState()==1) { throw new ServiceException("è¯¥æ¡æ¥å·¥å·²ç»ä¸åæ ¼å¤çäºï¼ä¸å 许å é¤"); // å 餿¥å·¥åå æ£æ¥æ¯å¦å·²ç»å®æä¸åæ ¼å¤ç List<QualityInspect> qualityInspects = qualityInspectMapper.selectList( Wrappers.<QualityInspect>lambdaQuery().eq(QualityInspect::getProductMainId, id) ); if (!qualityInspects.isEmpty()) { List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList( Wrappers.<QualityUnqualified>lambdaQuery() .in(QualityUnqualified::getInspectId, qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList())) ); if (!qualityUnqualifieds.isEmpty() && qualityUnqualifieds.get(0).getInspectState() == 1) { throw new ServiceException("该æ¥å·¥å·²å®æä¸åæ ¼å¤çï¼ä¸è½å é¤"); } } ProductionProductMain productionProductMain = productionProductMainMapper.selectById(id); //该æ¥å·¥å¯¹åºçå·¥èºè·¯çº¿è¯¦æ ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId()); ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(Wrappers.<ProductionProductOutput>lambdaQuery().eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())).get(0); /*å 餿 ¸ç®*/ ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList( Wrappers.<ProductionProductOutput>lambdaQuery().eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()) ).get(0); salesLedgerProductionAccountingMapper.delete( new LambdaQueryWrapper<SalesLedgerProductionAccounting>() .eq(SalesLedgerProductionAccounting::getProductMainId, productionProductMain.getId()) ); /*æ´æ°å·¥ååç产订å*/ ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId()); if (productWorkOrder != null && productionProductOutput != null) { BigDecimal outputQty = productionProductOutput.getQuantity() == null ? BigDecimal.ZERO : productionProductOutput.getQuantity(); @@ -368,16 +649,19 @@ BigDecimal completeQty = productWorkOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productWorkOrder.getCompleteQuantity(); BigDecimal validQuantity = outputQty.subtract(scrapQty); productWorkOrder.setCompleteQuantity(completeQty.subtract(validQuantity)); productWorkOrder.setActualEndTime(null); productWorkOrderMapper.updateById(productWorkOrder); } else { throw new ServiceException("æä½å¤±è´¥ï¼å·¥åä¿¡æ¯æäº§åºè®°å½ä¸åå¨"); } //夿æ¯å¦æ¯æåä¸éå·¥åº List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())); if (productProcessRouteItem.getDragSort() != null && productProcessRouteItems != null && productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) { List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList( Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()) ); if (productProcessRouteItem.getDragSort() != null && productProcessRouteItems != null && productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) { ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); if (productOrder != null) { BigDecimal orderCompleteQty = productOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productOrder.getCompleteQuantity(); @@ -392,31 +676,30 @@ throw new ServiceException("å ³èçç产订åä¸åå¨"); } } //å é¤è´¨æ£ qualityInspectMapper.selectList( new LambdaQueryWrapper<QualityInspect>() .eq(QualityInspect::getProductMainId, productionProductMain.getId()) ).forEach(q -> { qualityInspectParamMapper.delete( new LambdaQueryWrapper<QualityInspectParam>() .eq(QualityInspectParam::getInspectId, q.getId())); .eq(QualityInspectParam::getInspectId, q.getId()) ); qualityInspectMapper.deleteById(q.getId()); stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()); stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()); }); // å é¤äº§åºè®°å½ productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>() .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())); //å é¤æå ¥è®°å½ productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>() .eq(ProductionProductInput::getProductMainId, productionProductMain.getId())); //å 餿¥åºçå ¥åºè®°å½ productionProductOutputMapper.delete( new LambdaQueryWrapper<ProductionProductOutput>() .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()) ); productionProductInputMapper.delete( new LambdaQueryWrapper<ProductionProductInput>() .eq(ProductionProductInput::getProductMainId, productionProductMain.getId()) ); stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode()); //å é¤ä¸éè¦è´¨æ£çåæ ¼å ¥åº stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode()); //å é¤æå ¥å¯¹åºçåºåºè®°å½ stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode()); // å é¤ä¸»è¡¨ productionProductMainMapper.deleteById(productionProductMain.getId()); return true; } @@ -429,49 +712,39 @@ @Override public List<ProductionProductMainDto> getByProductWorkOrderId(Long productWorkOrderId) { List<ProductionProductMainDto> productionProductMainDtos = productionProductMainMapper.getByProductWorkOrderId(productWorkOrderId); if (productionProductMainDtos == null || productionProductMainDtos.isEmpty()) { return productionProductMainDtos; } // æ¶éææäº§å主记å½ID List<Long> productMainIds = productionProductMainDtos.stream() .map(ProductionProductMainDto::getId) .collect(Collectors.toList()); // æ¹éæ¥è¯¢ææç¸å ³çè´¨æ£è®°å½ List<QualityInspect> qualityInspects = qualityInspectMapper.selectList( Wrappers.<QualityInspect>lambdaQuery() .in(QualityInspect::getProductMainId, productMainIds) ); if (!qualityInspects.isEmpty()) { // æ¶éææè´¨æ£è®°å½ID List<Long> inspectIds = qualityInspects.stream() .map(QualityInspect::getId) .collect(Collectors.toList()); // æ¹éæ¥è¯¢ææç¸å ³çä¸åæ ¼å¤çè®°å½ List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList( Wrappers.<QualityUnqualified>lambdaQuery() .in(QualityUnqualified::getInspectId, inspectIds) ); // æå»ºè´¨æ£IDå°ä¸åæ ¼å¤çè®°å½çæ å° Map<Long, QualityUnqualified> inspectIdToUnqualifiedMap = qualityUnqualifieds.stream() .collect(Collectors.toMap(QualityUnqualified::getInspectId, q -> q, (q1, q2) -> q1)); // æå»ºäº§å主IDå°è´¨æ£è®°å½çæ å° Map<Long, QualityInspect> productMainIdToInspectMap = qualityInspects.stream() .collect(Collectors.toMap(QualityInspect::getProductMainId, q -> q, (q1, q2) -> q1)); // å ³èå¤çç»æå°äº§åä¸»è®°å½ productionProductMainDtos.forEach(p -> { QualityInspect qualityInspect = productMainIdToInspectMap.get(p.getId()); if (qualityInspect != null) { // ä¸è¯æ°é p.setDefectiveQuantity( qualityInspect.getDefectiveQuantity()); // åæ ¼æ°é = æ¥å·¥æ°é-æ¥åºæ°é-ä¸è¯æ°é p.setDefectiveQuantity(qualityInspect.getDefectiveQuantity()); p.setQualifiedQty(p.getQuantity().subtract(p.getScrapQty()).subtract(p.getDefectiveQuantity())); QualityUnqualified qualityUnqualified = inspectIdToUnqualifiedMap.get(qualityInspect.getId()); if (qualityUnqualified != null) { @@ -480,7 +753,7 @@ } }); } return productionProductMainDtos; } } } src/main/java/com/ruoyi/quality/mapper/QualityUnqualifiedMapper.java
@@ -3,7 +3,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.quality.pojo.QualityInspect; import com.ruoyi.quality.pojo.QualityUnqualified; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -13,22 +12,21 @@ @Mapper public interface QualityUnqualifiedMapper extends BaseMapper<QualityUnqualified> { IPage<QualityUnqualified> qualityUnqualifiedListPage(Page page, @Param("qualityUnqualified") QualityUnqualified qualityUnqualified); List<QualityUnqualified> qualityUnqualifiedExport(@Param("qualityUnqualified") QualityUnqualified qualityUnqualified); QualityUnqualified getUnqualified(@Param("id") Integer id); //æå¨æ°å¢ä¸åæ ¼çæ¶å,æ ¹æ®äº§ååç§°åè§æ ¼åå·æ¥åºå¯¹åºçè§æ ¼åå·id // æå¨æ°å¢ä¸åæ ¼æ¶ï¼æ ¹æ®äº§ååç§°åè§æ ¼åå·æ¥è¯¢å¯¹åºç产ååå· ID Long getModelId(@Param("productName") String productName, @Param("model") String model); //æ ¹æ®å·¥åºåç§°å表æ¥è¯¢è¢«é离çä¸åæ ¼è®°å½ List<QualityUnqualified> selectUnqualifiedByProcessNames(@Param("processNames") List<String> processNames); // æ ¹æ®ç产订ååååºå·¥åºåç§°å表æ¥è¯¢æªè§£é¤é离çä¸åæ ¼è®°å½ List<QualityUnqualified> selectUnqualifiedByProductOrderAndProcessNames(@Param("productOrderId") Long productOrderId, @Param("processNames") List<String> processNames); /** * æ¥è¯¢ä¸åæ ¼è®°å½çç产订åä¿¡æ¯ * @return * æ¥è¯¢ä¸åæ ¼è®°å½å ³èçç产订åä¿¡æ¯ã */ List<QualityUnqualified> selectUnqualifiedWithProductionOrder(); } } src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -10,6 +10,7 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; import com.ruoyi.common.utils.HackLoopTableRenderPolicy; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.procurementrecord.service.ProcurementRecordService; @@ -33,7 +34,7 @@ import com.ruoyi.quality.service.IQualityInspectParamService; import com.ruoyi.quality.service.IQualityInspectService; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.stock.pojo.StockUninventory; import com.ruoyi.stock.support.FinishedProductStockDimensionResolver; import lombok.AllArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -78,6 +79,9 @@ private ProductOrderMapper productOrderMapper; @Autowired private ISysNoticeService sysNoticeService; // è§£ææåå ¥åºç»´åº¦ã @Autowired private FinishedProductStockDimensionResolver finishedProductStockDimensionResolver; @Override public int add(QualityInspectDto qualityInspectDto) { @@ -156,16 +160,30 @@ qualityUnqualified.setInspectId(qualityInspect.getId()); qualityUnqualifiedMapper.insert(qualityUnqualified); } else { //åæ ¼å ¥åº // åæ ¼å ¥åº Integer inspectType = qualityInspect.getInspectType(); //ç产æåæ·»å å®¡æ ¸æµç¨ï¼åæåä¸å®¡æ ¸ if (inspectType != null && inspectType.equals(2)) { stockUtils.addStock(qualityInspect.getProductModelId(), qualityInspect.getQuantity(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), qualityInspect.getId()); boolean isFinishedProduct = inspectType != null && inspectType.equals(2); // æåéè¦å®¡æ ¸ // æ ¹æ®æ¯å¦æåéæ©å ¥åºæ¹å¼ String processCategory = null; String voltage = null; if (isFinishedProduct && qualityInspect.getProductMainId() != null) { processCategory = finishedProductStockDimensionResolver.resolveProcessCategory(qualityInspect.getProductMainId()); voltage = finishedProductStockDimensionResolver.resolveVoltage(qualityInspect.getProductMainId()); } if (isFinishedProduct) { stockUtils.addStock(qualityInspect.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), qualityInspect.getId(), processCategory, voltage); } else { stockUtils.addStockNoReview(qualityInspect.getProductModelId(), qualityInspect.getQuantity(), stockUtils.addStockNoReview(qualityInspect.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), qualityInspect.getId()); } // ä¸è¯æ°é>0çå ¥ä¸åæ ¼åºå if (qualityInspect.getDefectiveQuantity().compareTo(BigDecimal.ZERO) > 0) { stockUtils.addUnStockNoReview(qualityInspect.getProductModelId(), qualityInspect.getDefectiveQuantity(), StockInUnQualifiedRecordTypeEnum.QUALITYINSPECT_UNSTOCK_IN.getCode(), qualityInspect.getId()); } } qualityInspect.setInspectState(1);//å·²æäº¤ return qualityInspectMapper.updateById(qualityInspect); src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -26,6 +26,7 @@ import com.ruoyi.quality.pojo.QualityUnqualified; import com.ruoyi.quality.service.IQualityInspectService; import com.ruoyi.quality.service.IQualityUnqualifiedService; import com.ruoyi.stock.support.FinishedProductStockDimensionResolver; import com.ruoyi.stock.service.StockUninventoryService; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; @@ -35,7 +36,6 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Collections; import java.util.List; @AllArgsConstructor @@ -51,6 +51,10 @@ private ProductProcessRouteItemMapper productProcessRouteItemMapper; private ProductWorkOrderMapper productWorkOrderMapper; private StockUninventoryService stockUninventoryService; /** * è§£ææååæµå ¥åºç»´åº¦ã */ private FinishedProductStockDimensionResolver finishedProductStockDimensionResolver; @Override public IPage<QualityUnqualified> qualityUnqualifiedListPage(Page page, QualityUnqualified qualityUnqualified) { @@ -143,10 +147,12 @@ case "è®©æ¥æ¾è¡": //è°ç¨æäº¤åæ ¼çæ¥å£ // 2 æ¯æå-éè¦å®¡æ ¸ 1 æ¯åæå-ä¸éè¦å®¡æ ¸ if (qualityInspect.getInspectType().equals(2)) { if (qualityInspect.getInspectType().equals(1)) { stockUtils.addStockNoReview(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId()); } else { stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId()); String processCategory = finishedProductStockDimensionResolver.resolveProcessCategory(qualityInspect.getProductMainId()); String voltage = finishedProductStockDimensionResolver.resolveVoltage(qualityInspect.getProductMainId()); stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId(), processCategory, voltage); } break; case "é离": @@ -196,7 +202,9 @@ // åæ¶é离 è°ç¨æäº¤åæ ¼çæ¥å£ QualityInspect qualityInspect = qualityInspectService.getById(unqualified.getInspectId()); if (ObjectUtils.isNotNull(qualityInspect) && qualityInspect.getInspectType().equals(2)) { stockUtils.addStock(modelId, unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.LIFT_THE_QUARANTINE.getCode(), unqualified.getId()); String processCategory = finishedProductStockDimensionResolver.resolveProcessCategory(qualityInspect.getProductMainId()); String voltage = finishedProductStockDimensionResolver.resolveVoltage(qualityInspect.getProductMainId()); stockUtils.addStock(modelId, unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.LIFT_THE_QUARANTINE.getCode(), unqualified.getId(), processCategory, voltage); } else { stockUtils.addStockNoReview(modelId, unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.LIFT_THE_QUARANTINE.getCode(), unqualified.getId()); } src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -155,13 +155,13 @@ @PostMapping("/export") public void export(HttpServletResponse response, SalesLedgerDto salesLedgerDto) { Page page = new Page(-1,-1); IPage<SalesLedger> salesLedgerIPage = listPage(page, salesLedgerDto); ExcelUtil<SalesLedger> util = new ExcelUtil<SalesLedger>(SalesLedger.class); IPage<SalesLedgerDto> salesLedgerIPage = listPage(page, salesLedgerDto); ExcelUtil<SalesLedgerDto> util = new ExcelUtil<SalesLedgerDto>(SalesLedgerDto.class); if(salesLedgerIPage == null){ util.exportExcel(response, new ArrayList<>(), "éå®å°è´¦æ°æ®"); return; } List<SalesLedger> list = salesLedgerIPage.getRecords(); List<SalesLedgerDto> list = salesLedgerIPage.getRecords(); util.exportExcel(response, list, "éå®å°è´¦æ°æ®"); } @@ -174,8 +174,8 @@ Page page = new Page(); page.setCurrent(-1); page.setSize(-1); IPage<SalesLedger> salesLedgerIPage = listPage(page, salesLedgerDto); ExcelUtil<SalesLedger> util = new ExcelUtil<SalesLedger>(SalesLedger.class); IPage<SalesLedgerDto> salesLedgerIPage = listPage(page, salesLedgerDto); ExcelUtil<SalesLedgerDto> util = new ExcelUtil<SalesLedgerDto>(SalesLedgerDto.class); util.exportExcel(response, salesLedgerIPage == null ? new ArrayList<>() : salesLedgerIPage.getRecords(), "导åºå¼ç¥¨ç»è®°å表"); } @@ -270,8 +270,8 @@ * æ¥è¯¢éå®å°è´¦å表 */ @GetMapping("/listPage") public IPage<SalesLedger> listPage(Page page, SalesLedgerDto salesLedgerDto) { IPage<SalesLedger> iPage = salesLedgerService.selectSalesLedgerListPage(page, salesLedgerDto); public IPage<SalesLedgerDto> listPage(Page page, SalesLedgerDto salesLedgerDto) { IPage<SalesLedgerDto> iPage = salesLedgerService.selectSalesLedgerListPage(page, salesLedgerDto); // æ¥è¯¢ç»æä¸ºç©º,ç´æ¥è¿å if (CollectionUtils.isEmpty(iPage.getRecords())) { @@ -362,4 +362,4 @@ public R getSalesLedgerWithProductsLoss(Long salesLedgerId) { return R.ok(salesLedgerService.getSalesLedgerWithProductsLoss(salesLedgerId)); } } } src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -1,37 +1,23 @@ package com.ruoyi.sales.dto; import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.time.LocalDate; import java.util.Date; import java.util.List; @Data public class SalesLedgerDto { private Long id; private String salesContractNo; private String customerContractNo; private String projectName; @JsonFormat(pattern = "yyyy-MM-dd") private Date entryDate; @EqualsAndHashCode(callSuper = true) public class SalesLedgerDto extends SalesLedger { private String entryDateStart; private String entryDateEnd; private String salesman; private Long customerId; private String customerName; private String entryPerson; private String remarks; private String attachmentMaterials; @TableField(exist = false) @JsonFormat(pattern = "yyyy-MM-dd") @@ -39,9 +25,9 @@ @TableField(exist = false) private String invoiceNo; @TableField(exist = false) private String createUser; private Boolean hasChildren = false; private List<SalesLedgerProduct> productData; @@ -49,18 +35,17 @@ private List<CommonFile> SalesLedgerFiles; private Integer type; @ApiModelProperty(value = "ç¾è®¢æ¥æ") private LocalDate executionDate; private Boolean status; @ApiModelProperty(value = "仿¬¾æ¹å¼") private String paymentMethod; @TableField(exist = false) @ApiModelProperty(value = "åå·") private String model; @ApiModelProperty(value = "äº¤è´§æ¥æ") private LocalDate deliveryDate; @TableField(exist = false) @ApiModelProperty(value = "çµå") private String voltage; @ApiModelProperty(value = "æ¯å¦ç产") @JsonAlias("isProduce") private Boolean produce; @TableField(exist = false) @ApiModelProperty(value = "c") private String qty; } src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
@@ -52,7 +52,7 @@ * @param salesLedgerDto * @return */ IPage<SalesLedger> selectSalesLedgerListPage(Page page, @Param("salesLedgerDto") SalesLedgerDto salesLedgerDto); IPage<SalesLedgerDto> selectSalesLedgerListPage(Page page, @Param("salesLedgerDto") SalesLedgerDto salesLedgerDto); /** * ææä»½ç»è®¡è®¢åæ°ãéå®é¢ï¼æ¯æäº§å大类ã客æ·åç§°çéï¼ src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -1,6 +1,7 @@ package com.ruoyi.sales.pojo; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.annotations.ApiModelProperty; @@ -180,6 +181,7 @@ * æ¯å¦ç产 */ @ApiModelProperty(value = "æ¯å¦ç产") @JsonAlias("isProduce") @TableField(value = "is_produce") private Boolean produce; } src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -38,7 +38,7 @@ List<MonthlyAmountDto> getAmountHalfYear(Integer type); IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto); IPage<SalesLedgerDto> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto); AjaxResult importData(MultipartFile file); src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -606,7 +606,7 @@ } @Override public IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto) { public IPage<SalesLedgerDto> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto) { return salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto); } src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -8,6 +8,7 @@ import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import com.ruoyi.stock.dto.FinishedProductTreeDto; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.execl.StockInventoryExportData; import com.ruoyi.stock.service.StockInventoryService; @@ -47,6 +48,13 @@ return R.ok(stockInventoryDtoIPage); } @GetMapping("/finishedProductList") @ApiOperation("æ¥è¯¢æååºåæ ") public R finishedProductList(StockInventoryDto stockInventoryDto) { List<FinishedProductTreeDto> list = stockInventoryService.finishedProductList(stockInventoryDto); return R.ok(list); } @GetMapping("/pageListCombinedStockInventory") @Operation(summary = "å页æ¥è¯¢èååºåå表") src/main/java/com/ruoyi/stock/dto/FinishedProductTreeDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,31 @@ package com.ruoyi.stock.dto; import lombok.Data; import java.util.List; @Data public class FinishedProductTreeDto { private Long id; private Long parentId; private String productName; private String label; private Long productId; private Long productModelId; private String model; private String materialCode; private String processCategory; private String voltage; private List<FinishedProductTreeDto> children; } src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java
@@ -3,40 +3,39 @@ import com.ruoyi.stock.pojo.StockInRecord; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data public class StockInRecordDto extends StockInRecord { /** * 产ååç§° */ @Schema(description = "产ååç§°") private String productName; /** * 产åè§æ ¼ */ @Schema(description = "产ååå·") private String model; /** * 产åæå· */ @Schema(description = "ç©æç¼ç ") private String materialCode; /** * 产ååä½ */ @Schema(description = "åä½") private String unit; @Schema(description = "æ¶é´å符串") private String timeStr; @Schema(description = "å建人") private String createBy; //ç°åé @Schema(description = "å½ååºå") private String currentStock; //订å @Schema(description = "订åç¼å·") private String npsNo; //å·¥å @Schema(description = "å·¥åç¼å·") private String workOrderNo; // é¡¶é¨ç¶äº§åid @Schema(description = "顶级ç¶çº§äº§åID") private Long topParentProductId; } src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
@@ -17,21 +17,17 @@ private String unit; private String materialCode; private String productModelName; //å ¥åºç±»å private String recordType; //å ¥åºç±»å对åºçid private Long recordId; @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate reportDate; //åºåææ¥æ¥è¯¢å段 @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate startMonth; @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate endMonth; @@ -39,16 +35,13 @@ private BigDecimal totalStockIn; private BigDecimal totalStockOut; private BigDecimal currentStock; private BigDecimal unLockedQuantity; //产åid private BigDecimal unLockedQuantity; private Long productId; @Schema(description = "é¡¶é¨ç¶äº§åid") @Schema(description = "顶级ç¶çº§äº§åID") private Long topParentProductId; @Schema(description = "åºåç±»åï¼qualified(åæ ¼)ãunqualified(ä¸åæ ¼)") @Schema(description = "åºåç±»å") private String stockType; @Schema(description = "åæ ¼åºåæ°é") @@ -57,16 +50,16 @@ @Schema(description = "ä¸åæ ¼åºåæ°é") private BigDecimal unQualifiedQuantity; @Schema(description = "åæ ¼åºåå»ç»æ°é") @Schema(description = "åæ ¼å»ç»æ°é") private BigDecimal qualifiedLockedQuantity; @Schema(description = "ä¸åæ ¼åºåå»ç»æ°é") @Schema(description = "ä¸åæ ¼å»ç»æ°é") private BigDecimal unQualifiedLockedQuantity; @Schema(description = "åæ ¼åºåæªå»ç»æ°é") @Schema(description = "åæ ¼å¯ç¨æ°é") private BigDecimal qualifiedUnLockedQuantity; @Schema(description = "ä¸åæ ¼åºåæªå»ç»æ°é") @Schema(description = "ä¸åæ ¼å¯ç¨æ°é") private BigDecimal unQualifiedUnLockedQuantity; @Schema(description = "åæ ¼åºåID") @@ -75,9 +68,10 @@ @Schema(description = "ä¸åæ ¼åºåID") private Long unQualifiedId; @Schema(description = "åæ ¼åºåæ¹å·") @Schema(description = "åæ ¼æ¹æ¬¡å·") private String qualifiedBatchNo; @Schema(description = "ä¸åæ ¼åºåæ¹å·") @Schema(description = "ä¸åæ ¼æ¹æ¬¡å·") private String unQualifiedBatchNo; } } src/main/java/com/ruoyi/stock/execl/StockInRecordExportData.java
@@ -12,19 +12,32 @@ @Excel(name = "å ¥åºæ¹æ¬¡") private String inboundBatches; @Excel(name = "产ååç§°") private String productName; @Excel(name = "è§æ ¼åå·") @Excel(name = "åå·") private String model; @Excel(name = "æå·") @Excel(name = "ç©æç¼ç ") private String materialCode; @Excel(name = "åä½") private String unit; @Excel(name = "å ¥åºæ¥æº") @Excel(name = "æåç±»å«") private String processCategory; @Excel(name = "çµå") private String voltage; @Excel(name = "è®°å½ç±»å") private String recordType; @Excel(name = "å ¥åºæ°é") private String stockInNum; @Excel(name = "å ¥åºæ¶é´") @Excel(name = "å建æ¶é´") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
@@ -10,14 +10,20 @@ @Excel(name = "产ååç§°") private String productName; @Excel(name = "è§æ ¼") @Excel(name = "åå·") private String model; @Excel(name = "åä½") private String unit; @Excel(name = "æå·") @Excel(name = "ç©æç¼ç ") private String materialCode; @Excel(name = "æåç±»å«") private String processCategory; @Excel(name = "çµå") private String voltage; @Excel(name = "åæ ¼åºåæ¹å·") private String qualifiedBatchNo; @@ -42,11 +48,4 @@ @Excel(name = "夿³¨") private String remark; // // @Excel(name = "ææ°æ´æ°æ¶é´") // @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") // private LocalDateTime updateTime; } src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -52,4 +52,6 @@ BigDecimal selectTotalByDate(@Param("now") LocalDate now); List<StockInventoryDto> selectProductList(); List<StockInventoryDto> selectFinishedProductInventoryList(@Param("ew") StockInventoryDto stockInventoryDto); } src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
@@ -78,4 +78,10 @@ @ApiModelProperty("æ¹å·") private String batchNo; @ApiModelProperty("å·¥èºç±»å«") private String processCategory; @ApiModelProperty("çµå") private String voltage; } src/main/java/com/ruoyi/stock/pojo/StockInventory.java
@@ -64,6 +64,12 @@ @ApiModelProperty("夿³¨") private String remark; @ApiModelProperty("å·¥èºç±»å«") private String processCategory; @ApiModelProperty("çµå") private String voltage; @ApiModelProperty("æ¹å·") private String batchNo; } src/main/java/com/ruoyi/stock/service/StockInventoryService.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.web.domain.R; import com.ruoyi.stock.dto.FinishedProductTreeDto; import com.ruoyi.stock.dto.StockInRecordDto; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.pojo.StockInRecord; @@ -12,6 +13,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.util.List; /** * <p> @@ -25,6 +27,8 @@ IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto); List<FinishedProductTreeDto> finishedProductList(StockInventoryDto stockInventoryDto); IPage<StockInventoryDto> pageListCombinedStockInventory(Page page, StockInventoryDto stockInventoryDto); Boolean addstockInventory(StockInventoryDto stockInventoryDto); src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -10,12 +10,11 @@ import com.ruoyi.common.utils.EnumUtil; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.stock.dto.StockInRecordDto; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.dto.StockUninventoryDto; import com.ruoyi.stock.execl.StockInRecordExportData; import com.ruoyi.stock.mapper.StockInRecordMapper; import com.ruoyi.stock.mapper.StockInventoryMapper; @@ -30,6 +29,8 @@ import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; @Service @@ -49,7 +50,6 @@ return stockInRecordMapper.listPage(page, stockInRecordDto); } // æ°å¢å ¥åº @Override @Transactional(rollbackFor = Exception.class) public Long add(StockInRecordDto stockInRecordDto) { @@ -57,18 +57,14 @@ stockInRecordDto.setInboundBatches(no); StockInRecord stockInRecord = new StockInRecord(); BeanUtils.copyProperties(stockInRecordDto, stockInRecord); int insertRows = stockInRecordMapper.insert(stockInRecord); Long insertId = stockInRecord.getId(); return insertRows > 0 ? insertId : null; } @Override @Transactional(rollbackFor = Exception.class) public int update(Long id, StockInRecordDto stockInRecordDto) { // å¤æå¯¹è±¡æ¯å¦åå¨ StockInRecord stockInRecord = stockInRecordMapper.selectById(id); if (stockInRecord == null) { throw new BaseException("è¯¥å ¥åºè®°å½ä¸åå¨,æ æ³æ´æ°!!!"); @@ -84,33 +80,28 @@ public int batchDelete(List<Long> ids) { for (Long id : ids) { StockInRecord stockInRecord = stockInRecordMapper.selectById(id); if (stockInRecord.getType().equals("0")) { StockInventory stockInventory = stockInventoryMapper.selectOne( new LambdaQueryWrapper<StockInventory>() .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()) .eq(StockInventory::getBatchNo, stockInRecord.getBatchNo()) ); if ("0".equals(stockInRecord.getType())) { StockInventory stockInventory = findQualifiedInventory(stockInRecord); if (stockInventory == null) { throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产å,æ æ³å é¤!!!"); } else { StockInventoryDto stockInRecordDto = new StockInventoryDto(); stockInRecordDto.setProductModelId(stockInventory.getProductModelId()); stockInRecordDto.setQualitity(stockInRecord.getStockInNum()); stockInventoryMapper.updateSubtractStockInventory(stockInRecordDto); throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产åï¼æ æ³å é¤!!!"); } } else if (stockInRecord.getType().equals("1")) { stockInventory.setQualitity(defaultDecimal(stockInventory.getQualitity()).subtract(defaultDecimal(stockInRecord.getStockInNum()))); stockInventory.setVersion(stockInventory.getVersion() == null ? 1 : stockInventory.getVersion() + 1); stockInventory.setUpdateTime(LocalDateTime.now()); stockInventoryMapper.updateById(stockInventory); } else if ("1".equals(stockInRecord.getType())) { StockUninventory stockUninventory = stockUninventoryMapper.selectOne( new LambdaQueryWrapper<StockUninventory>() .eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId()) .eq(StockUninventory::getBatchNo, stockInRecord.getBatchNo())); .eq(StockUninventory::getBatchNo, stockInRecord.getBatchNo()) ); if (stockUninventory == null) { throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产å,æ æ³å é¤!!!"); } else { StockUninventoryDto stockUninventoryDto = new StockUninventoryDto(); stockUninventoryDto.setProductModelId(stockUninventory.getProductModelId()); stockUninventoryDto.setQualitity(stockInRecord.getStockInNum()); stockUninventoryMapper.updateSubtractStockUnInventory(stockUninventoryDto); throw new BaseException("åºåè®°å½ä¸æ²¡æå¯¹åºç产åï¼æ æ³å é¤!!!"); } stockUninventory.setQualitity(defaultDecimal(stockUninventory.getQualitity()).subtract(defaultDecimal(stockInRecord.getStockInNum()))); stockUninventory.setVersion(stockUninventory.getVersion() == null ? 1 : stockUninventory.getVersion() + 1); stockUninventory.setUpdateTime(LocalDateTime.now()); stockUninventoryMapper.updateById(stockUninventory); } } return stockInRecordMapper.deleteBatchIds(ids); @@ -120,10 +111,14 @@ public void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto) { List<StockInRecordExportData> list = stockInRecordMapper.listStockInRecordExportData(stockInRecordDto); for (StockInRecordExportData stockInRecordExportData : list) { if (stockInRecordExportData.getType().equals("0")) { stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockInQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue()); if ("0".equals(stockInRecordExportData.getType())) { stockInRecordExportData.setRecordType( EnumUtil.fromCode(StockInQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue() ); } else { stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockInUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue()); stockInRecordExportData.setRecordType( EnumUtil.fromCode(StockInUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue() ); } } ExcelUtil<StockInRecordExportData> util = new ExcelUtil<>(StockInRecordExportData.class); @@ -139,11 +134,30 @@ public int updateStockInRecord(StockInRecordDto stockInRecordDto) { LoginUser loginUser = SecurityUtils.getLoginUser(); try { stockInventoryService.addApproveByPurchase(loginUser, stockInRecordDto,stockInRecordDto.getId()); stockInventoryService.addApproveByPurchase(loginUser, stockInRecordDto, stockInRecordDto.getId()); } catch (Exception e) { e.printStackTrace(); } stockInRecordDto.setApproveStatus(1); return stockInRecordMapper.updateById(stockInRecordDto); } // åæ ¼å ¥åºåéæä¸åºååå¹¶ä¸è´çå¯ä¸é®æ¥æ¾ã private StockInventory findQualifiedInventory(StockInRecord stockInRecord) { LambdaQueryWrapper<StockInventory> queryWrapper = new LambdaQueryWrapper<StockInventory>() .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()) .orderByAsc(StockInventory::getId); String processCategory = StringUtils.trimToEmpty(stockInRecord.getProcessCategory()); String voltage = StringUtils.trimToEmpty(stockInRecord.getVoltage()); if (StringUtils.isNotBlank(processCategory) || StringUtils.isNotBlank(voltage)) { queryWrapper.eq(StockInventory::getProcessCategory, processCategory); queryWrapper.eq(StockInventory::getVoltage, voltage); } List<StockInventory> inventories = stockInventoryMapper.selectList(queryWrapper); return inventories.isEmpty() ? null : inventories.get(0); } private BigDecimal defaultDecimal(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; } } src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -2,7 +2,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -16,9 +15,12 @@ import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.web.domain.R; import com.ruoyi.stock.dto.FinishedProductTreeDto; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.stock.dto.StockInRecordDto; @@ -43,18 +45,15 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * <p> * åºå表 æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-01-21 04:16:36 */ @Service public class StockInventoryServiceImpl extends ServiceImpl<StockInventoryMapper, StockInventory> implements StockInventoryService { @@ -80,17 +79,54 @@ return stockInventoryMapper.pagestockInventory(page, stockInventoryDto); } /** * æ¥è¯¢æååºåæ ã * è¿åç»ææ²¿ç¨åºç¡èµæäº§åæ ï¼å¶åèç¹è¡¥å æååºå维度ï¼åå·ãå·¥åºåç±»ãçµåã */ @Override public List<FinishedProductTreeDto> finishedProductList(StockInventoryDto stockInventoryDto) { List<StockInventoryDto> inventoryList = stockInventoryMapper.selectFinishedProductInventoryList(stockInventoryDto); if (inventoryList.isEmpty()) { return new ArrayList<>(); } List<Product> allProducts = productMapper.selectList(null); Map<Long, Product> productMap = new HashMap<>(); Map<Long, List<Product>> childrenMap = new HashMap<>(); for (Product product : allProducts) { productMap.put(product.getId(), product); childrenMap.computeIfAbsent(product.getParentId(), key -> new ArrayList<>()).add(product); } Map<Long, List<FinishedProductTreeDto>> leafMap = buildFinishedProductLeafMap(inventoryList); Set<Long> visibleProductIds = collectVisibleProductIds(leafMap.keySet(), productMap); List<FinishedProductTreeDto> result = new ArrayList<>(); for (Product rootProduct : allProducts) { if (!isFinishedRoot(rootProduct)) { continue; } FinishedProductTreeDto rootNode = buildProductNode(rootProduct); rootNode.setChildren(buildFinishedChildren(rootProduct.getId(), childrenMap, leafMap, visibleProductIds)); if (!rootNode.getChildren().isEmpty()) { result.add(rootNode); } } return result; } @Override public IPage<StockInventoryDto> pageListCombinedStockInventory(Page page, StockInventoryDto stockInventoryDto) { return stockInventoryMapper.pageListCombinedStockInventory(page, stockInventoryDto); } //å ¥åºè°ç¨-æ·»å å ¥åºè®°å½ /** * åæ ¼å ¥åºï¼å çæå ¥åºè®°å½ï¼åèµ°å®¡æ¹æµã */ @Override @Transactional(rollbackFor = Exception.class) public Boolean addstockInventory(StockInventoryDto stockInventoryDto) { List<StockInventory> stockInventoryList = stockInventoryMapper.selectList(null); //æ°å¢å ¥åºè®°å½åæ·»å åºå StockInRecordDto stockInRecordDto = new StockInRecordDto(); stockInRecordDto.setRecordId(stockInventoryDto.getRecordId()); stockInRecordDto.setRecordType(stockInventoryDto.getRecordType()); @@ -99,22 +135,17 @@ stockInRecordDto.setRemark(stockInventoryDto.getRemark()); stockInRecordDto.setWarnNum(stockInventoryDto.getWarnNum()); stockInRecordDto.setLockedQuantity(stockInventoryDto.getLockedQuantity()); stockInRecordDto.setProcessCategory(normalizeDimension(stockInventoryDto.getProcessCategory())); stockInRecordDto.setVoltage(normalizeDimension(stockInventoryDto.getVoltage())); stockInRecordDto.setApproveStatus(0); stockInRecordDto.setType("0"); if (stockInventoryDto.getBatchNo() == null || stockInventoryDto.getBatchNo().isEmpty()) { if (StringUtils.isBlank(stockInventoryDto.getBatchNo())) { String batchNo; // è·åå½åæä»½ï¼ä¸¤ä½ï¼ LocalDate now = LocalDate.now(); String monthFlag = now.format(DateTimeFormatter.ofPattern("MM")); // è·åå½åæä»½çæå¤§æµæ°´å· int maxSeq = getCurrentMonthMaxSeq(stockInventoryDto, monthFlag, stockInventoryList); // æ°æµæ°´å· = æå¤§æµæ°´å· + 1 int newSeq = maxSeq + 1; String seqStr = String.format("%03d", newSeq); // ç»è£ batchNo ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId()); batchNo = stockInventoryDto.getMaterialCode() + productModel.getModel() + "P" + monthFlag + seqStr; stockInRecordDto.setBatchNo(batchNo); @@ -133,21 +164,15 @@ return true; } /** * æ¥è¯¢å½åæä»½å·²åå¨çæå¤§æµæ°´å· */ private static int getCurrentMonthMaxSeq(StockInventoryDto dto, String monthFlag, List<StockInventory> existingList) { int maxSeq = 0; String prefix = dto.getMaterialCode() + dto.getProductModelName() + "P" + monthFlag; // æ£åå¹é ï¼åç¼ + 3使°å Pattern pattern = Pattern.compile(Pattern.quote(prefix) + "(\\d{3})"); for (StockInventory item : existingList) { String batchNo = item.getBatchNo(); if (batchNo == null) continue; if (batchNo == null) { continue; } Matcher matcher = pattern.matcher(batchNo); if (matcher.find()) { int seq = Integer.parseInt(matcher.group(1)); @@ -156,10 +181,10 @@ } } } return maxSeq; } @Override public void addApproveByPurchase(LoginUser loginUser, StockInRecordDto stockInRecordDto, Long id) throws Exception { ApproveProcessVO approveProcessVO = new ApproveProcessVO(); approveProcessVO.setApproveType(9); @@ -175,100 +200,77 @@ } /** * å®é å ¥åº * * @param stockInRecord * æåºåå¯ä¸é®åå¹¶åºåã * æåä½¿ç¨ product_model_id + processCategory + voltageï¼å ¶ä»å ¥åºåªæ product_model_idã */ @Override public void updateOrCreateStockInventory(StockInRecord stockInRecord) { // å æ¥è¯¢åºå表ä¸çäº§åæ¯å¦åå¨ LambdaQueryWrapper<StockInventory> queryWrapper = new QueryWrapper<StockInventory>().lambda() .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()); // æ ¹æ® batchNo æ¯å¦ä¸ºç©ºæå»ºä¸åçæ¥è¯¢æ¡ä»¶ if (stockInRecord.getBatchNo() != null && !stockInRecord.getBatchNo().isEmpty()) { queryWrapper.eq(StockInventory::getBatchNo, stockInRecord.getBatchNo()); } else { queryWrapper.isNull(StockInventory::getBatchNo); } StockInventory oldStockInventory = stockInventoryMapper.selectOne(queryWrapper); String processCategory = normalizeDimension(stockInRecord.getProcessCategory()); String voltage = normalizeDimension(stockInRecord.getVoltage()); StockInventory oldStockInventory = findInventoryForMerge( stockInRecord.getProductModelId(), processCategory, voltage ); if (ObjectUtils.isEmpty(oldStockInventory)) { // ä¸åå¨åæ°å¢ StockInventory newStockInventory = new StockInventory(); newStockInventory.setProductModelId(stockInRecord.getProductModelId()); newStockInventory.setQualitity(stockInRecord.getStockInNum()); newStockInventory.setQualitity(defaultDecimal(stockInRecord.getStockInNum())); newStockInventory.setVersion(1); newStockInventory.setRemark(stockInRecord.getRemark()); newStockInventory.setLockedQuantity(stockInRecord.getLockedQuantity()); newStockInventory.setLockedQuantity(defaultDecimal(stockInRecord.getLockedQuantity())); newStockInventory.setWarnNum(stockInRecord.getWarnNum()); newStockInventory.setBatchNo(stockInRecord.getBatchNo()); newStockInventory.setProcessCategory(processCategory); newStockInventory.setVoltage(voltage); newStockInventory.setBatchNo(StringUtils.trimToEmpty(stockInRecord.getBatchNo())); stockInventoryMapper.insert(newStockInventory); } else { // åå¨åæ´æ° LambdaUpdateWrapper<StockInventory> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()); // æ ¹æ® batchNo æ¯å¦ä¸ºç©ºæå»ºä¸åçæ´æ°æ¡ä»¶ if (stockInRecord.getBatchNo() != null && !stockInRecord.getBatchNo().isEmpty()) { updateWrapper.eq(StockInventory::getBatchNo, stockInRecord.getBatchNo()); } else { updateWrapper.isNull(StockInventory::getBatchNo); } updateWrapper .setSql(stockInRecord.getStockInNum() != null, "qualitity = qualitity + " + stockInRecord.getStockInNum()) .setSql(true, "version = version + 1") .set(stockInRecord.getRemark() != null && !stockInRecord.getRemark().isEmpty(), StockInventory::getRemark, stockInRecord.getRemark()) .set(stockInRecord.getWarnNum() != null, StockInventory::getWarnNum, stockInRecord.getWarnNum()) .setSql(stockInRecord.getLockedQuantity() != null, "locked_quantity = locked_quantity + " + stockInRecord.getLockedQuantity()) .set(StockInventory::getUpdateTime, new Date()); stockInventoryMapper.update(null, updateWrapper); return; } oldStockInventory.setQualitity(defaultDecimal(oldStockInventory.getQualitity()).add(defaultDecimal(stockInRecord.getStockInNum()))); oldStockInventory.setVersion(oldStockInventory.getVersion() == null ? 1 : oldStockInventory.getVersion() + 1); if (StringUtils.isNotBlank(stockInRecord.getRemark())) { oldStockInventory.setRemark(stockInRecord.getRemark()); } if (stockInRecord.getWarnNum() != null) { oldStockInventory.setWarnNum(stockInRecord.getWarnNum()); } if (stockInRecord.getLockedQuantity() != null) { oldStockInventory.setLockedQuantity(defaultDecimal(oldStockInventory.getLockedQuantity()).add(stockInRecord.getLockedQuantity())); } oldStockInventory.setProcessCategory(processCategory); oldStockInventory.setVoltage(voltage); oldStockInventory.setUpdateTime(LocalDateTime.now()); stockInventoryMapper.updateById(oldStockInventory); } //åæåç´æ¥å ¥åº /** * ä¸å®¡æ ¸å ¥åºï¼ç´æ¥åå ¥å ¥åºè®°å½ååºåã */ @Override @Transactional(rollbackFor = Exception.class) public Boolean addstockInventoryNoReview(StockInventoryDto stockInventoryDto) { //æ°å¢å ¥åºè®°å½åæ·»å åºå StockInRecordDto stockInRecordDto = new StockInRecordDto(); stockInRecordDto.setRecordId(stockInventoryDto.getRecordId()); stockInRecordDto.setRecordType(stockInventoryDto.getRecordType()); stockInRecordDto.setStockInNum(stockInventoryDto.getQualitity()); stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); stockInRecordDto.setRemark(stockInventoryDto.getRemark()); stockInRecordDto.setWarnNum(stockInventoryDto.getWarnNum()); stockInRecordDto.setLockedQuantity(stockInventoryDto.getLockedQuantity()); stockInRecordDto.setProcessCategory(normalizeDimension(stockInventoryDto.getProcessCategory())); stockInRecordDto.setVoltage(normalizeDimension(stockInventoryDto.getVoltage())); stockInRecordDto.setBatchNo(stockInventoryDto.getBatchNo()); stockInRecordDto.setType("0"); stockInRecordService.add(stockInRecordDto); //åè¿è¡æ°å¢åºåæ°éåºå //å æ¥è¯¢åºå表ä¸çäº§åæ¯å¦åå¨ï¼ä¸å卿°å¢ï¼å卿´æ° StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()) .eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo())); if (ObjectUtils.isEmpty(oldStockInventory)) { StockInventory newStockInventory = new StockInventory(); newStockInventory.setProductModelId(stockInventoryDto.getProductModelId()); newStockInventory.setQualitity(stockInventoryDto.getQualitity()); newStockInventory.setVersion(1); newStockInventory.setRemark(stockInventoryDto.getRemark()); newStockInventory.setLockedQuantity(stockInventoryDto.getLockedQuantity()); newStockInventory.setWarnNum(stockInventoryDto.getWarnNum()); stockInventoryMapper.insert(newStockInventory); } else { stockInventoryMapper.updateAddStockInventory(stockInventoryDto); } updateOrCreateStockInventory(toStockInRecord(stockInRecordDto)); return true; } //åºåºè°ç¨ @Override @Transactional(rollbackFor = Exception.class) public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) { // æ°å¢åºåºè®°å½ StockOutRecordDto stockOutRecordDto = new StockOutRecordDto(); stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId()); stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType()); @@ -276,7 +278,8 @@ stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); stockOutRecordDto.setType("0"); stockOutRecordService.add(stockOutRecordDto); if (ObjectUtils.isEmpty(stockInventoryDto.getBatchNo())) { if (StringUtils.isBlank(stockInventoryDto.getBatchNo()) && !usesDimensionIdentity(normalizeDimension(stockInventoryDto.getProcessCategory()), normalizeDimension(stockInventoryDto.getVoltage()))) { List<StockInventory> stockInventories = stockInventoryMapper.selectList(new QueryWrapper<StockInventory>().lambda() .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()) .orderByAsc(StockInventory::getId)); @@ -286,14 +289,14 @@ BigDecimal remainingQty = stockInventoryDto.getQualitity(); for (StockInventory stockInventory : stockInventories) { BigDecimal lockedQty = stockInventory.getLockedQuantity() == null ? BigDecimal.ZERO : stockInventory.getLockedQuantity(); BigDecimal availableQty = stockInventory.getQualitity().subtract(lockedQty); BigDecimal lockedQty = defaultDecimal(stockInventory.getLockedQuantity()); BigDecimal availableQty = defaultDecimal(stockInventory.getQualitity()).subtract(lockedQty); if (availableQty.compareTo(BigDecimal.ZERO) <= 0) { continue; } BigDecimal deductQty = remainingQty.min(availableQty); stockInventory.setQualitity(stockInventory.getQualitity().subtract(deductQty)); stockInventory.setQualitity(defaultDecimal(stockInventory.getQualitity()).subtract(deductQty)); stockInventory.setVersion(stockInventory.getVersion() == null ? 1 : stockInventory.getVersion() + 1); stockInventory.setUpdateTime(LocalDateTime.now()); stockInventoryMapper.updateById(stockInventory); @@ -306,55 +309,51 @@ ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId()); Product product = productMapper.selectById(productModel.getProductId()); throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "åºåä¸è¶³æ æ³åºåº"); throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "åºåä¸è¶³ï¼æ æ³åºåº"); } StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()) .eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo())); StockInventory oldStockInventory = findInventoryForMerge( stockInventoryDto.getProductModelId(), stockInventoryDto.getProcessCategory(), stockInventoryDto.getVoltage() ); if (ObjectUtils.isEmpty(oldStockInventory)) { throw new RuntimeException("产ååºåä¸åå¨"); } BigDecimal lockedQty = oldStockInventory.getLockedQuantity(); if (lockedQty == null) { lockedQty = BigDecimal.ZERO; } if (stockInventoryDto.getQualitity().compareTo(oldStockInventory.getQualitity().subtract(lockedQty)) > 0) { // æ¥è¯¢äº§åè§æ ¼å BigDecimal lockedQty = defaultDecimal(oldStockInventory.getLockedQuantity()); if (stockInventoryDto.getQualitity().compareTo(defaultDecimal(oldStockInventory.getQualitity()).subtract(lockedQty)) > 0) { ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId()); Product product = productMapper.selectById(productModel.getProductId()); throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "åºåä¸è¶³æ æ³åºåº"); throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "åºåä¸è¶³ï¼æ æ³åºåº"); } stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto); oldStockInventory.setQualitity(defaultDecimal(oldStockInventory.getQualitity()).subtract(stockInventoryDto.getQualitity())); oldStockInventory.setVersion(oldStockInventory.getVersion() == null ? 1 : oldStockInventory.getVersion() + 1); oldStockInventory.setUpdateTime(LocalDateTime.now()); stockInventoryMapper.updateById(oldStockInventory); return true; } @Override public R importStockInventory(MultipartFile file) { try { // æ¥è¯¢ææç产åå¹¶æå»ºæ å°ï¼æé«æ¥æ¾æç List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectProduct(); Map<String, SalesLedgerProduct> productMap = new HashMap<>(); for (SalesLedgerProduct product : salesLedgerProducts) { // 使ç¨äº§åç±»å«åè§æ ¼åå·ä½ä¸ºé® String key = product.getProductCategory() + "|" + product.getSpecificationModel(); productMap.put(key, product); } ExcelUtil<StockInventoryExportData> util = new ExcelUtil<StockInventoryExportData>(StockInventoryExportData.class); ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class); List<StockInventoryExportData> list = util.importExcel(file.getInputStream()); // è®°å½æªæ¾å°å¹é é¡¹çæ°æ® List<String> unmatchedRecords = new ArrayList<>(); // è®°å½å¤çç»æ int successCount = 0; for (StockInventoryExportData dto : list) { // æå»ºæ¥æ¾é® String key = dto.getProductName() + "|" + dto.getModel(); SalesLedgerProduct matchedProduct = productMap.get(key); if (matchedProduct != null) { // å¤çåæ ¼åºå if (dto.getQualifiedQuantity() != null && dto.getQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0) { StockInventoryDto stockInventoryDto = new StockInventoryDto(); stockInventoryDto.setRecordId(0L); @@ -363,8 +362,9 @@ stockInventoryDto.setRemark(dto.getRemark()); stockInventoryDto.setWarnNum(dto.getWarnNum()); stockInventoryDto.setBatchNo(dto.getQualifiedBatchNo()); stockInventoryDto.setProcessCategory(dto.getProcessCategory()); stockInventoryDto.setVoltage(dto.getVoltage()); // éªè¯åæ ¼å»ç»æ°é if (ObjectUtils.isNotEmpty(dto.getQualifiedLockedQuantity())) { if (dto.getQualifiedLockedQuantity().compareTo(dto.getQualifiedQuantity()) > 0) { throw new RuntimeException("åæ ¼å»ç»æ°éä¸è½è¶ è¿æ¬æ¬¡å¯¼å ¥çåæ ¼åºåæ°é"); @@ -379,7 +379,6 @@ successCount++; } // å¤çä¸åæ ¼åºå if (dto.getUnQualifiedQuantity() != null && dto.getUnQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0) { StockUninventoryDto stockUninventoryDto = new StockUninventoryDto(); stockUninventoryDto.setRecordId(0L); @@ -388,7 +387,6 @@ stockUninventoryDto.setRemark(dto.getRemark()); stockUninventoryDto.setBatchNo(dto.getUnQualifiedBatchNo()); // éªè¯ä¸åæ ¼å»ç»æ°é if (ObjectUtils.isNotEmpty(dto.getUnQualifiedLockedQuantity())) { if (dto.getUnQualifiedLockedQuantity().compareTo(dto.getUnQualifiedQuantity()) > 0) { throw new RuntimeException("ä¸åæ ¼å»ç»æ°éä¸è½è¶ è¿æ¬æ¬¡å¯¼å ¥çä¸åæ ¼åºåæ°é"); @@ -403,16 +401,14 @@ successCount++; } } else { // è®°å½æªå¹é ç产å String unmatchedRecord = "产ååç§°ï¼" + dto.getProductName() + "ï¼åå·ï¼" + dto.getModel(); String unmatchedRecord = "产ååç§°ï¼" + dto.getProductName() + "ï¼åå·ï¼" + dto.getModel() + " æªå¹é å°åºå产å"; unmatchedRecords.add(unmatchedRecord); } } // æå»ºè¿åä¿¡æ¯ StringBuilder message = new StringBuilder(); if (!unmatchedRecords.isEmpty()) { message.append("å¯¼å ¥æå " + successCount + " æ¡è®°å½ï¼ä»¥ä¸äº§åæªæ¾å°å¹é 项ï¼\n"); message.append("å¯¼å ¥æå ").append(successCount).append(" æ¡è®°å½ï¼ä»¥ä¸äº§åæªå¹é ï¼\n"); for (String record : unmatchedRecords) { message.append(record).append("\n"); } @@ -421,14 +417,13 @@ return R.ok("å¯¼å ¥æåï¼å ±å¤ç " + successCount + " æ¡è®°å½"); } catch (Exception e) { log.error("å¯¼å ¥åºå失败", e); return R.fail("å¯¼å ¥å¤±è´¥ï¼" + e.getMessage()); log.error("åºåå¯¼å ¥å¤±è´¥", e); return R.fail("åºåå¯¼å ¥å¤±è´¥ï¼" + e.getMessage()); } } @Override public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto) { List<StockInventoryExportData> list = stockInventoryMapper.listStockInventoryExportData(stockInventoryDto); ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class); util.exportExcel(response, list, "åºåä¿¡æ¯"); @@ -467,4 +462,132 @@ stockInventory.setLockedQuantity(stockInventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity())); return this.updateById(stockInventory); } } // å ¥åºåå¹¶å¯ä¸é®ï¼æåæç±»å«åçµåï¼å ¶ä½åªæäº§åè§æ ¼ã private StockInventory findInventoryForMerge(Long productModelId, String processCategory, String voltage) { LambdaQueryWrapper<StockInventory> queryWrapper = new LambdaQueryWrapper<StockInventory>() .eq(StockInventory::getProductModelId, productModelId) .orderByAsc(StockInventory::getId); if (usesDimensionIdentity(processCategory, voltage)) { queryWrapper.eq(StockInventory::getProcessCategory, normalizeDimension(processCategory)); queryWrapper.eq(StockInventory::getVoltage, normalizeDimension(voltage)); } List<StockInventory> inventories = stockInventoryMapper.selectList(queryWrapper); return inventories.isEmpty() ? null : inventories.get(0); } // å°å ¥åºè®°å½ DTO å¤å¶ä¸ºæä¹ åå®ä½ã private StockInRecord toStockInRecord(StockInRecordDto stockInRecordDto) { StockInRecord stockInRecord = new StockInRecord(); stockInRecord.setRecordId(stockInRecordDto.getRecordId()); stockInRecord.setRecordType(stockInRecordDto.getRecordType()); stockInRecord.setStockInNum(stockInRecordDto.getStockInNum()); stockInRecord.setProductModelId(stockInRecordDto.getProductModelId()); stockInRecord.setRemark(stockInRecordDto.getRemark()); stockInRecord.setType(stockInRecordDto.getType()); stockInRecord.setLockedQuantity(stockInRecordDto.getLockedQuantity()); stockInRecord.setWarnNum(stockInRecordDto.getWarnNum()); stockInRecord.setApproveStatus(stockInRecordDto.getApproveStatus()); stockInRecord.setBatchNo(stockInRecordDto.getBatchNo()); stockInRecord.setProcessCategory(stockInRecordDto.getProcessCategory()); stockInRecord.setVoltage(stockInRecordDto.getVoltage()); return stockInRecord; } // åªè¦å¸¦ææå维度ï¼å°±æç»´åº¦ä½ä¸ºå¯ä¸é®ã private boolean usesDimensionIdentity(String processCategory, String voltage) { return StringUtils.isNotBlank(processCategory) || StringUtils.isNotBlank(voltage); } private String normalizeDimension(String value) { return StringUtils.trimToEmpty(value); } private BigDecimal defaultDecimal(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; } private Map<Long, List<FinishedProductTreeDto>> buildFinishedProductLeafMap(List<StockInventoryDto> inventoryList) { Map<Long, List<FinishedProductTreeDto>> leafMap = new HashMap<>(); for (StockInventoryDto inventory : inventoryList) { FinishedProductTreeDto leafNode = new FinishedProductTreeDto(); leafNode.setId(inventory.getId() == null ? null : -inventory.getId()); leafNode.setParentId(inventory.getProductId()); leafNode.setProductId(inventory.getProductId()); leafNode.setProductModelId(inventory.getProductModelId()); leafNode.setProductName(inventory.getProductName()); leafNode.setLabel(buildLeafLabel(inventory)); leafNode.setModel(inventory.getModel()); leafNode.setMaterialCode(inventory.getMaterialCode()); leafNode.setProcessCategory(inventory.getProcessCategory()); leafNode.setVoltage(inventory.getVoltage()); leafNode.setChildren(new ArrayList<>()); leafMap.computeIfAbsent(inventory.getProductId(), key -> new ArrayList<>()).add(leafNode); } return leafMap; } private Set<Long> collectVisibleProductIds(Set<Long> leafProductIds, Map<Long, Product> productMap) { Set<Long> visibleIds = new HashSet<>(); for (Long productId : leafProductIds) { Long currentId = productId; while (currentId != null) { Product current = productMap.get(currentId); if (current == null) { break; } visibleIds.add(currentId); currentId = current.getParentId(); } } return visibleIds; } private List<FinishedProductTreeDto> buildFinishedChildren(Long parentId, Map<Long, List<Product>> childrenMap, Map<Long, List<FinishedProductTreeDto>> leafMap, Set<Long> visibleProductIds) { List<FinishedProductTreeDto> children = new ArrayList<>(); List<Product> childProducts = childrenMap.getOrDefault(parentId, new ArrayList<>()); for (Product childProduct : childProducts) { if (!visibleProductIds.contains(childProduct.getId())) { continue; } FinishedProductTreeDto childNode = buildProductNode(childProduct); List<FinishedProductTreeDto> subChildren = buildFinishedChildren(childProduct.getId(), childrenMap, leafMap, visibleProductIds); subChildren.addAll(leafMap.getOrDefault(childProduct.getId(), new ArrayList<>())); childNode.setChildren(subChildren); children.add(childNode); } return children; } private FinishedProductTreeDto buildProductNode(Product product) { FinishedProductTreeDto node = new FinishedProductTreeDto(); BeanUtils.copyProperties(product, node); node.setLabel(product.getProductName()); node.setChildren(new ArrayList<>()); return node; } private boolean isFinishedRoot(Product product) { return product.getParentId() == null && "æå".equals(StringUtils.trimToEmpty(product.getProductName())); } private String buildLeafLabel(StockInventoryDto inventory) { List<String> parts = new ArrayList<>(); if (StringUtils.isNotBlank(inventory.getProductName())) { parts.add(StringUtils.trim(inventory.getProductName())); } if (StringUtils.isNotBlank(inventory.getModel())) { parts.add(StringUtils.trim(inventory.getModel())); } if (StringUtils.isNotBlank(inventory.getProcessCategory())) { parts.add(StringUtils.trim(inventory.getProcessCategory())); } if (StringUtils.isNotBlank(inventory.getVoltage())) { parts.add(StringUtils.trim(inventory.getVoltage())); } return String.join(" / ", parts); } } src/main/java/com/ruoyi/stock/support/FinishedProductStockDimensionResolver.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,184 @@ package com.ruoyi.stock.support; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.production.mapper.ProductProcessMapper; import com.ruoyi.production.mapper.ProductProcessRouteItemMapper; import com.ruoyi.production.mapper.ProductionProductMainMapper; import com.ruoyi.production.mapper.ProductionProductOutputMapper; import com.ruoyi.production.pojo.ProductProcess; import com.ruoyi.production.pojo.ProductProcessRouteItem; import com.ruoyi.production.pojo.ProductionProductMain; import com.ruoyi.production.pojo.ProductionProductOutput; import org.springframework.stereotype.Component; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @Component public class FinishedProductStockDimensionResolver { private static final String PROCESS_COPPER = "å°é"; private static final String PROCESS_SILVER = "å°é¶"; private static final String PROCESS_CATEGORY_COPPER = "éæ"; private static final String PROCESS_CATEGORY_SILVER = "é¶æ"; private static final String VOLTAGE_PARAMETER = "çµå"; private final ProductionProductMainMapper productionProductMainMapper; private final ProductionProductOutputMapper productionProductOutputMapper; private final ProductProcessRouteItemMapper productProcessRouteItemMapper; private final ProductProcessMapper productProcessMapper; public FinishedProductStockDimensionResolver(ProductionProductMainMapper productionProductMainMapper, ProductionProductOutputMapper productionProductOutputMapper, ProductProcessRouteItemMapper productProcessRouteItemMapper, ProductProcessMapper productProcessMapper) { this.productionProductMainMapper = productionProductMainMapper; this.productionProductOutputMapper = productionProductOutputMapper; this.productProcessRouteItemMapper = productProcessRouteItemMapper; this.productProcessMapper = productProcessMapper; } /** * è§£ææåå ¥åºç±»å«ã * å½å·¥åºä¸ºå°éæ¶è¿åéæï¼å½å·¥åºä¸ºå°é¶æ¶è¿åé¶æã */ public String resolveProcessCategory(Long productMainId) { ProductionProductMain productionProductMain = loadProductionMain(productMainId); ProductProcessRouteItem routeItem = loadRouteItem(productionProductMain); if (routeItem.getProductRouteId() == null) { throw new ServiceException("å·¥èºè·¯çº¿æªç»å®å·¥èºæç»ï¼æ æ³ç¡®å®æåç±»å«"); } return resolveProcessCategoryByRouteId(routeItem.getProductRouteId()); } /** * è§£ææåå ¥åºçµåï¼æ¥æºäºæ¥å·¥ otherData ä¸çâçµåâåæ°ã */ public String resolveVoltage(Long productMainId) { List<ProductionProductOutput> outputs = loadOutputs(productMainId); for (ProductionProductOutput output : outputs) { String voltage = resolveVoltageValue(output.getOtherData()); if (StringUtils.isNotBlank(voltage)) { return voltage; } } throw new ServiceException("请é ç½®åæ°çµå"); } private ProductionProductMain loadProductionMain(Long productMainId) { if (productMainId == null) { throw new ServiceException("æ¥å·¥IDä¸è½ä¸ºç©º"); } ProductionProductMain productionProductMain = productionProductMainMapper.selectById(productMainId); if (productionProductMain == null) { throw new ServiceException("æ¥å·¥è®°å½ä¸åå¨ï¼æ æ³ç¡®å®æååºå维度"); } return productionProductMain; } private ProductProcessRouteItem loadRouteItem(ProductionProductMain productionProductMain) { if (productionProductMain.getProductProcessRouteItemId() == null) { throw new ServiceException("æ¥å·¥æªå ³èå·¥èºè·¯çº¿æç»ï¼æ æ³ç¡®å®æååºå维度"); } ProductProcessRouteItem routeItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId()); if (routeItem == null) { throw new ServiceException("å·¥èºè·¯çº¿æç»ä¸åå¨ï¼æ æ³ç¡®å®æååºå维度"); } return routeItem; } private List<ProductionProductOutput> loadOutputs(Long productMainId) { List<ProductionProductOutput> outputs = productionProductOutputMapper.selectList( new LambdaQueryWrapper<ProductionProductOutput>() .eq(ProductionProductOutput::getProductMainId, productMainId) ); if (CollectionUtils.isEmpty(outputs)) { throw new ServiceException("æ¥å·¥è¾åºè®°å½ä¸åå¨ï¼æ æ³ç¡®å®æååºå维度"); } return outputs; } private String resolveProcessCategoryByRouteId(Long productRouteId) { List<ProductProcessRouteItem> routeItems = productProcessRouteItemMapper.selectList( new LambdaQueryWrapper<ProductProcessRouteItem>() .eq(ProductProcessRouteItem::getProductRouteId, productRouteId) ); if (CollectionUtils.isEmpty(routeItems)) { throw new ServiceException("订åå·¥èºè·¯çº¿æªé 置工åºï¼æ æ³ç¡®å®æåç±»å«"); } Set<Long> processIds = routeItems.stream() .map(ProductProcessRouteItem::getProcessId) .filter(id -> id != null) .collect(Collectors.toSet()); if (processIds.isEmpty()) { throw new ServiceException("订åå·¥èºè·¯çº¿æªé 置工åºï¼æ æ³ç¡®å®æåç±»å«"); } List<ProductProcess> processes = productProcessMapper.selectBatchIds(processIds); Set<String> matchedCategories = processes.stream() .map(ProductProcess::getName) .filter(name -> PROCESS_COPPER.equals(name) || PROCESS_SILVER.equals(name)) .collect(Collectors.toCollection(LinkedHashSet::new)); if (matchedCategories.isEmpty()) { throw new ServiceException("订åå·¥èºè·¯çº¿æªé ç½®å°é/å°é¶å·¥åºï¼æ æ³ç¡®å®æåç±»å«"); } if (matchedCategories.size() > 1) { throw new ServiceException("订åå·¥èºè·¯çº¿åæ¶é ç½®äºå°éåå°é¶ï¼æ æ³ç¡®å®æåç±»å«"); } String matchedProcess = matchedCategories.iterator().next(); if (PROCESS_COPPER.equals(matchedProcess)) { return PROCESS_CATEGORY_COPPER; } return PROCESS_CATEGORY_SILVER; } private String resolveVoltageValue(String otherData) { if (StringUtils.isBlank(otherData)) { return null; } Object parsed; try { parsed = JSON.parse(otherData); } catch (Exception ex) { throw new ServiceException("æ¥å·¥åæ°æ ¼å¼éè¯¯ï¼æ æ³è§£æçµå"); } String voltage = StringUtils.trim(findVoltageValue(parsed)); return StringUtils.isBlank(voltage) ? null : voltage; } private String findVoltageValue(Object node) { if (node instanceof JSONArray) { JSONArray array = (JSONArray) node; for (Object item : array) { String voltage = findVoltageValue(item); if (StringUtils.isNotBlank(voltage)) { return voltage; } } return null; } if (node instanceof JSONObject) { JSONObject object = (JSONObject) node; if (VOLTAGE_PARAMETER.equals(StringUtils.trim(object.getString("parameterItem")))) { String value = StringUtils.trim(object.getString("value")); if (StringUtils.isNotBlank(value)) { return value; } } for (Object value : object.values()) { String voltage = findVoltageValue(value); if (StringUtils.isNotBlank(voltage)) { return voltage; } } } return null; } } src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -58,6 +58,9 @@ <if test="c.productOrderNpsNo != null and c.productOrderNpsNo != ''"> and po.nps_no like concat('%',#{c.productOrderNpsNo},'%') </if> <if test="c.processName != null and c.processName != ''"> and pp.NAME like concat('%',#{c.processName},'%') </if> order by pwo.priority asc, po.id desc, ppri.drag_sort asc </select> src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -154,10 +154,13 @@ <select id="checkPreviousProcessReported" resultType="java.lang.Boolean"> SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END FROM production_product_main ppm JOIN product_work_order pwo ON ppm.work_order_id = pwo.id JOIN product_process_route_item ppri ON pwo.product_process_route_item_id = ppri.id WHERE ppri.product_route_id = #{productRouteId} AND ppri.drag_sort = #{currentDragSort} - 1 FROM product_work_order current_pwo JOIN product_process_route_item current_ppri ON current_pwo.product_process_route_item_id = current_ppri.id JOIN product_work_order previous_pwo ON previous_pwo.product_order_id = current_pwo.product_order_id JOIN product_process_route_item previous_ppri ON previous_pwo.product_process_route_item_id = previous_ppri.id JOIN production_product_main ppm ON ppm.work_order_id = previous_pwo.id WHERE current_pwo.id = #{workOrderId} AND previous_ppri.product_route_id = current_ppri.product_route_id AND previous_ppri.drag_sort = #{currentDragSort} - 1 </select> </mapper> src/main/resources/mapper/quality/QualityUnqualifiedMapper.xml
@@ -24,7 +24,7 @@ ELSE false END AS method FROM quality_unqualified qu LEFT JOIN product_model pm ON qu.model = pm.model LEFT JOIN product_model pm ON qu.model = pm.model and qu.product_id = pm.product_id where 1=1 <if test="qualityUnqualified.inspectType != null "> @@ -40,9 +40,10 @@ AND check_time >= DATE_FORMAT(#{qualityUnqualified.entryDateStart},'%Y-%m-%d') </if> <if test="qualityUnqualified.entryDateEnd != null and qualityUnqualified.entryDateEnd != '' "> AND check_time <= DATE_FORMAT(#{qualityUnqualified.entryDateEnd},'%Y-%m-%d') AND check_time <= DATE_FORMAT(#{qualityUnqualified.entryDateEnd},'%Y-%m-%d') </if> </select> <select id="qualityUnqualifiedExport" resultType="com.ruoyi.quality.pojo.QualityUnqualified"> SELECT qu.*, @@ -61,6 +62,7 @@ AND product_name = #{qualityUnqualified.productName} </if> </select> <select id="getUnqualified" resultType="com.ruoyi.quality.pojo.QualityUnqualified"> SELECT qu.id, @@ -84,27 +86,32 @@ ELSE false END AS method FROM quality_unqualified qu LEFT JOIN product_model pm ON qu.model = pm.model AND pm.product_id = qu.product_id LEFT JOIN quality_inspect qi ON qu.inspect_id = qi.id LEFT JOIN product_model pm ON qu.model = pm.model AND pm.product_id = qu.product_id LEFT JOIN quality_inspect qi ON qu.inspect_id = qi.id where 1=1 and qu.id = #{id} and qu.id = #{id} </select> <select id="getModelId" resultType="java.lang.Long"> select pm.id from product_model pm left join product p on pm.product_id=p.id where pm.model=#{model} and p.product_name=#{productName} left join product p on pm.product_id = p.id where pm.model = #{model} and p.product_name = #{productName} </select> <select id="selectUnqualifiedByProcessNames" resultType="com.ruoyi.quality.pojo.QualityUnqualified"> <select id="selectUnqualifiedByProductOrderAndProcessNames" resultType="com.ruoyi.quality.pojo.QualityUnqualified"> SELECT DISTINCT qu.* FROM quality_unqualified qu JOIN quality_inspect qi ON qu.inspect_id = qi.id JOIN production_product_main ppm ON qi.product_main_id = ppm.id JOIN product_work_order pwo ON ppm.work_order_id = pwo.id WHERE qi.process IN <foreach collection="processNames" item="processName" open="(" separator="," close=")"> #{processName} </foreach> AND pwo.product_order_id = #{productOrderId} AND qu.deal_result = 'é离' AND qu.quarantine_lifted = false </select> @@ -121,4 +128,4 @@ WHERE po.id IS NOT NULL GROUP BY po.id </select> </mapper> </mapper> src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -43,7 +43,7 @@ </where> </select> <select id="selectSalesLedgerListPage" resultType="com.ruoyi.sales.pojo.SalesLedger"> <select id="selectSalesLedgerListPage" resultType="com.ruoyi.sales.dto.SalesLedgerDto"> SELECT T1.id, T1.sales_contract_no, T1.customer_contract_no, @@ -68,6 +68,9 @@ T1.is_produce AS produce, T1.delivery_date, DATEDIFF(T1.delivery_date, CURDATE()) AS delivery_days_diff, product_summary.model, '' AS voltage, product_summary.qty, CASE WHEN shipping_status_counts.total_count = 0 THEN false WHEN shipping_status_counts.unshipped_count = 0 THEN true @@ -83,6 +86,15 @@ FROM shipping_info GROUP BY sales_ledger_id ) shipping_status_counts ON T1.id = shipping_status_counts.sales_ledger_id LEFT JOIN ( SELECT sales_ledger_id, GROUP_CONCAT(IFNULL(specification_model, '') ORDER BY id SEPARATOR ',') AS model, GROUP_CONCAT(IFNULL(CAST(quantity AS CHAR), '') ORDER BY id SEPARATOR ',') AS qty FROM sales_ledger_product WHERE type = 1 GROUP BY sales_ledger_id ) product_summary ON T1.id = product_summary.sales_ledger_id <where> <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' "> AND T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%') src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -40,6 +40,12 @@ <if test="params.recordType != null and params.recordType != ''"> AND sir.record_type = #{params.recordType} </if> <if test="params.processCategory != null and params.processCategory != ''"> AND sir.process_category = #{params.processCategory} </if> <if test="params.voltage != null and params.voltage != ''"> AND sir.voltage = #{params.voltage} </if> <if test="params.topParentProductId != null and params.topParentProductId > 0"> AND p.id in (select id from product_tree) </if> @@ -83,6 +89,12 @@ <if test="params.recordType != null and params.recordType != ''"> and sir.record_type = #{params.recordType} </if> <if test="params.processCategory != null and params.processCategory != ''"> and sir.process_category = #{params.processCategory} </if> <if test="params.voltage != null and params.voltage != ''"> and sir.voltage = #{params.voltage} </if> <if test="params.topParentProductId != null and params.topParentProductId > 0"> and p.id in (select id from product_tree) </if> @@ -113,4 +125,4 @@ ORDER BY sir.id DESC </select> </mapper> </mapper> src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -12,6 +12,9 @@ <result column="version" property="version"/> <result column="locked_quantity" property="lockedQuantity"/> <result column="warn_num" property="warnNum"/> <result column="process_category" property="processCategory"/> <result column="voltage" property="voltage"/> <result column="batch_no" property="batchNo"/> </resultMap> <update id="updateAddStockInventory"> update stock_inventory @@ -64,6 +67,8 @@ (si.qualitity - COALESCE(si.locked_quantity, 0)) AS un_locked_quantity, pm.model, si.remark, si.process_category as processCategory, si.voltage, pm.unit, pm.material_code as materialCode, p.product_name, @@ -78,6 +83,12 @@ AND (p2.product_name != 'åæå' OR p2.product_name IS NULL) <if test="ew.productName != null and ew.productName != ''"> AND p.product_name LIKE CONCAT('%', #{ew.productName}, '%') </if> <if test="ew.processCategory != null and ew.processCategory != ''"> AND si.process_category = #{ew.processCategory} </if> <if test="ew.voltage != null and ew.voltage != ''"> AND si.voltage = #{ew.voltage} </if> </select> @@ -109,6 +120,8 @@ MAX(version) as version, model, MAX(remark) as remark, processCategory, voltage, unit, product_name, product_id, @@ -133,6 +146,8 @@ (si.qualitity - COALESCE(si.locked_quantity, 0)) as un_locked_quantity, pm.model, si.remark, si.process_category as processCategory, si.voltage as voltage, pm.unit, p.product_name, p.id as product_id, @@ -161,6 +176,8 @@ (su.qualitity - COALESCE(su.locked_quantity, 0)) as un_locked_quantity, pm.model, su.remark, '' as processCategory, '' as voltage, pm.unit, p.product_name, p.id as product_id, @@ -184,7 +201,7 @@ and combined.product_id in (select id from product_tree) </if> </where> group by product_model_id, model, unit, product_name, product_id, qualifiedBatchNo, unQualifiedBatchNo, materialCode, product_id, qualifiedBatchNo, unQualifiedBatchNo group by product_model_id, model, unit, product_name, product_id, unQualifiedBatchNo, materialCode, processCategory, voltage </select> <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData"> @@ -207,6 +224,8 @@ model, unit, product_name, processCategory, voltage, MAX(warn_num) as warn_num, MAX(remark) as remark, MAX(update_time) as update_time, @@ -227,6 +246,8 @@ pm.model, pm.unit, p.product_name, si.process_category as processCategory, si.voltage as voltage, p.id as product_id, si.batch_no as qualifiedBatchNo, null as unQualifiedBatchNo, @@ -250,6 +271,8 @@ pm.model, pm.unit, p.product_name, '' as processCategory, '' as voltage, p.id as product_id, null as qualifiedBatchNo, su.batch_no as unQualifiedBatchNo, @@ -271,18 +294,32 @@ and combined.product_id in (select id from product_tree) </if> </where> group by product_model_id, model, unit, product_name, qualifiedBatchNo, unQualifiedBatchNo, materialCode group by product_model_id, model, unit, product_name, unQualifiedBatchNo, materialCode, processCategory, voltage </select> <select id="stockInventoryPage" resultType="com.ruoyi.stock.dto.StockInRecordDto"> select sir.*,si.qualitity as current_stock, pm.model, sir.process_category as processCategory, sir.voltage, pm.unit, pm.material_code as materialCode, p.product_name, su.nick_name as create_by from stock_in_record sir left join stock_inventory si on sir.product_model_id = si.product_model_id left join stock_inventory si on sir.product_model_id = si.product_model_id and ( (ifnull(sir.process_category, '') != '' or ifnull(sir.voltage, '') != '') and ifnull(sir.process_category, '') = ifnull(si.process_category, '') and ifnull(sir.voltage, '') = ifnull(si.voltage, '') or ifnull(sir.process_category, '') = '' and ifnull(sir.voltage, '') = '' and ifnull(si.process_category, '') = '' and ifnull(si.voltage, '') = '' and si.product_model_id = sir.product_model_id ) left join product_model pm on sir.product_model_id = pm.id left join product p on pm.product_id = p.id left join sys_user su on sir.create_user = su.user_id @@ -432,6 +469,8 @@ (si.qualitity - COALESCE(si.locked_quantity, 0)) as un_locked_quantity, pm.model, si.remark, si.process_category as processCategory, si.voltage, pm.unit, p.product_name, p.id as product_id @@ -440,4 +479,35 @@ left join product p on pm.product_id = p.id </select> </mapper> <select id="selectFinishedProductInventoryList" resultType="com.ruoyi.stock.dto.StockInventoryDto"> select si.id, si.product_model_id, si.process_category as processCategory, si.voltage, pm.model, pm.material_code as materialCode, pm.unit, p.product_name, p.id as product_id from stock_inventory si left join product_model pm on si.product_model_id = pm.id left join product p on pm.product_id = p.id left join product pp on p.parent_id = pp.id <where> pp.product_name = 'æå' <if test="ew.productName != null and ew.productName != ''"> and (p.product_name like concat('%', #{ew.productName}, '%') or pm.model like concat('%', #{ew.productName}, '%') or pm.material_code like concat('%', #{ew.productName}, '%')) </if> <if test="ew.processCategory != null and ew.processCategory != ''"> and si.process_category = #{ew.processCategory} </if> <if test="ew.voltage != null and ew.voltage != ''"> and si.voltage = #{ew.voltage} </if> </where> order by p.id asc, pm.id asc, si.id asc </select> </mapper>