From 1342f568f4b6470efdfc69be7bb153e2b12762f9 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期二, 31 三月 2026 17:00:57 +0800
Subject: [PATCH] feat:1.销售,采购,库存,质检模块产品添加批号,供应商 2.销售产品关联批号,供应商递归查询

---
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java |  148 +++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 125 insertions(+), 23 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
index 272ea6b..7175825 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -1,8 +1,10 @@
 package com.ruoyi.production.service.impl;
 
+import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -12,12 +14,12 @@
 import com.ruoyi.basic.pojo.Product;
 import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
-import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.procurementrecord.utils.StockUtils;
-import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.dto.DrawMaterialDto;
 import com.ruoyi.production.dto.ProductionProductMainDto;
 import com.ruoyi.production.mapper.*;
 import com.ruoyi.production.pojo.*;
@@ -30,7 +32,6 @@
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import com.ruoyi.production.mapper.ProductionProductMainMapper;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
@@ -39,6 +40,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -138,23 +140,82 @@
         productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId());
         productionProductMain.setWorkOrderId(dto.getWorkOrderId());
         productionProductMain.setStatus(0);
+        productionProductMain.setDeviceId(dto.getDeviceId());
         productionProductMainMapper.insert(productionProductMain);
-        /*鏂板鎶ュ伐鎶曞叆琛�*/
-        List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId());
-        if (productStructureDtos.isEmpty()) {
-            //濡傛灉璇ュ伐搴忔病鏈変骇鍝佺粨鏋勭殑鎶曞叆鍝�,閭h繖涓姇鍏ュ搧鍜屼骇鍑哄搧鏄悓涓�涓�
-            ProductStructureDto productStructureDto = new ProductStructureDto();
-            productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId());
-            productStructureDto.setUnitQuantity(BigDecimal.ONE);
-            productStructureDtos.add(productStructureDto);
+        /* 鏂板鎶ュ伐鎶曞叆琛� */
+        ProductWorkOrder WorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
+        if (WorkOrder == null) {
+            throw new RuntimeException("宸ュ崟涓嶅瓨鍦�");
         }
-        for (ProductStructureDto productStructureDto : productStructureDtos) {
 
-            ProductionProductInput productionProductInput = new ProductionProductInput();
-            productionProductInput.setProductModelId(productStructureDto.getProductModelId());
-            productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
-            productionProductInput.setProductMainId(productionProductMain.getId());
-            productionProductInputMapper.insert(productionProductInput);
+        ProductOrder order = productOrderMapper.selectById(WorkOrder.getProductOrderId());
+        if (order == null) {
+            throw new RuntimeException("浜у搧璁㈠崟涓嶅瓨鍦�");
+        }
+        List<DrawMaterialDto> drawMaterialList = dto.getDrawMaterialList();
+        if (!CollectionUtils.isEmpty(drawMaterialList)) {
+
+            // 鐗╂枡Map
+            List<DrawMaterialDto> existingMaterialList = JSON.parseArray(order.getDrawMaterials(), DrawMaterialDto.class);
+            if (CollectionUtils.isEmpty(existingMaterialList)) {
+                throw new RuntimeException("鍙鐢ㄧ墿鏂欏垪琛ㄤ负绌�");
+            }
+
+            Map<String, DrawMaterialDto> materialMap = existingMaterialList.stream()
+                    .collect(Collectors.toMap(
+                            materialDto -> materialDto.getProductModelId() + "_" +
+                                    (materialDto.getBatchNo() == null ? "" : materialDto.getBatchNo()) + "_" +
+                                    (materialDto.getCustomer() == null ? "" : materialDto.getCustomer()),
+                            Function.identity(),
+                            (existing, replacement) -> existing
+                    ));
+
+            // 澶勭悊鎶ュ伐鐗╂枡
+            List<ProductionProductInput> inputList = new ArrayList<>();
+
+            for (DrawMaterialDto drawMaterial : drawMaterialList) {
+                Long modelId = drawMaterial.getProductModelId();
+                BigDecimal reportQty = drawMaterial.getReportQty();
+
+                String key = drawMaterial.getProductModelId() + "_" +
+                        (drawMaterial.getBatchNo() == null ? "" : drawMaterial.getBatchNo()) + "_" +
+                        (drawMaterial.getCustomer() == null ? "" : drawMaterial.getCustomer());
+
+                DrawMaterialDto material = materialMap.get(key);
+                if (material == null) {
+                    throw new RuntimeException("鐗╂枡涓嶅瓨鍦�: 浜у搧鍨嬪彿ID=" + modelId +
+                            ", 鎵规鍙�=" + drawMaterial.getBatchNo() +
+                            ", 瀹㈡埛=" + drawMaterial.getCustomer());
+                }
+
+                // 楠岃瘉搴撳瓨
+                BigDecimal availableQty = material.getRequisitionQty().subtract(reportQty);
+                if (availableQty.compareTo(BigDecimal.valueOf(0)) < 0) {
+                    throw new RuntimeException(String.format("鐗╂枡%s搴撳瓨涓嶈冻锛屽彲鐢�:%s锛岄渶棰�:%s",
+                            modelId, availableQty, reportQty));
+                }
+
+                // 鏇存柊鍙鐢�
+                material.setRequisitionQty(availableQty);
+
+                // 鏋勫缓鎶曞叆璁板綍
+                ProductionProductInput input = new ProductionProductInput();
+                input.setProductModelId(modelId);
+                input.setQuantity(reportQty);
+                input.setProductMainId(productionProductMain.getId());
+                input.setRemark(drawMaterial.getRemark());
+                input.setBatchNo(drawMaterial.getBatchNo());
+                input.setCustomer(drawMaterial.getCustomer());
+                inputList.add(input);
+            }
+
+            if (!inputList.isEmpty()) {
+                for (ProductionProductInput productionProductInput : inputList) {
+                    productionProductInputMapper.insert(productionProductInput);
+                }
+                order.setDrawMaterials(JSON.toJSONString(existingMaterialList));
+                productOrderMapper.updateById(order);
+            }
         }
         /*鏂板鎶ュ伐浜у嚭琛�*/
         ProductionProductOutput productionProductOutput = new ProductionProductOutput();
@@ -162,6 +223,7 @@
         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() : "");
         productionProductOutputMapper.insert(productionProductOutput);
         //鍚堟牸鏁伴噺=鎶ュ伐鏁伴噺
         BigDecimal productQty = productionProductOutput.getQuantity();
@@ -178,18 +240,27 @@
                     inspectType = 2;
                     process = null;
                 }
+                ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId());
+                ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
+                if (productOrder == null) {
+                    throw new RuntimeException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+                }
+
+
                 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(productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty()));
                 qualityInspect.setProcess(process);
                 qualityInspect.setInspectState(0);
                 qualityInspect.setInspectType(inspectType);
                 qualityInspect.setProductMainId(productionProductMain.getId());
                 qualityInspect.setProductModelId(productModel.getId());
+                qualityInspect.setBatchNo(productOrder.getBatchNo());
+                qualityInspect.setManufacturingTeam(productOrder.getManufacturingTeam());
                 qualityInspectMapper.insert(qualityInspect);
                 List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process);
                 if (qualityTestStandard.size() > 0) {
@@ -205,9 +276,12 @@
                                 qualityInspectParamMapper.insert(param);
                             });
                 }
-            }else {
+            } else {
                 //鐩存帴鍏ュ簱
-                stockUtils.addStock(productProcessRouteItem.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
+                String customer = "闀挎不甯傝酱鎵垮埗閫犳湁闄愬叕鍙�";
+                stockUtils.addStock(productProcessRouteItem.getProductModelId(), productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty()),
+                        StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId(),order.getBatchNo(),customer
+                );
             }
             /*鏇存柊宸ュ崟鍜岀敓浜ц鍗�*/
             ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
@@ -263,10 +337,10 @@
     public Boolean removeProductMain(Long id) {
         //鍒ゆ柇璇ユ潯鎶ュ伐鏄惁涓嶅悎鏍煎鐞�,濡傛灉涓嶅悎鏍煎鐞嗕簡锛屽垯涓嶅厑璁稿垹闄�
         List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(Wrappers.<QualityInspect>lambdaQuery().eq(QualityInspect::getProductMainId, id));
-        if (qualityInspects.size() > 0){
+        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) {
+            if (qualityUnqualifieds.size() > 0 && qualityUnqualifieds.get(0).getInspectState() == 1) {
                 throw new ServiceException("璇ユ潯鎶ュ伐宸茬粡涓嶅悎鏍煎鐞嗕簡锛屼笉鍏佽鍒犻櫎");
             }
         }
@@ -320,9 +394,37 @@
                     new LambdaQueryWrapper<QualityInspectParam>()
                             .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());
         });
 
+        ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
+
+        List<DrawMaterialDto> materialDtoList = JSON.parseArray(productOrder.getDrawMaterials(), DrawMaterialDto.class);
+
+        // 鎵归噺鏌ヨ骞舵瀯寤篗ap
+        Map<Long, BigDecimal> usedQuantityMap = productionProductInputMapper.selectList(
+                        new LambdaQueryWrapper<ProductionProductInput>()
+                                .eq(ProductionProductInput::getProductMainId, productionProductMain.getId())
+                                .in(ProductionProductInput::getProductModelId,
+                                        materialDtoList.stream()
+                                                .map(DrawMaterialDto::getProductModelId)
+                                                .collect(Collectors.toList()))
+                ).stream()
+                .collect(Collectors.groupingBy(
+                        ProductionProductInput::getProductModelId,
+                        Collectors.reducing(BigDecimal.ZERO, ProductionProductInput::getQuantity, BigDecimal::add)
+                ));
+
+        // 鏇存柊鎵�鏈夌墿鏂�
+        materialDtoList.forEach(dto -> {
+            BigDecimal usedQty = usedQuantityMap.getOrDefault(dto.getProductModelId(), BigDecimal.ZERO);
+            dto.setRequisitionQty(dto.getRequisitionQty().add(usedQty));
+        });
+
+        // 鏇存柊璁㈠崟
+        productOrder.setDrawMaterials(JSON.toJSONString(materialDtoList));
+        productOrderMapper.updateById(productOrder);
+
         // 鍒犻櫎浜у嚭璁板綍
         productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
                 .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()));

--
Gitblit v1.9.3