已修改13个文件
260 ■■■■ 文件已修改
src/main/java/com/ruoyi/basic/controller/ProductController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/ProductModelDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/IProductModelService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/quality/QualityInspectMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/ProductController.java
@@ -17,8 +17,6 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
@@ -143,4 +141,14 @@
        ExcelUtil<ProductModelExportDto> excelUtil = new ExcelUtil<>(ProductModelExportDto.class);
        excelUtil.importTemplateExcel(response, "产品规格导入模板");
    }
    /**
     * 向下复制型号等
     */
    @Log(title = "向下复制型号等", businessType = BusinessType.INSERT)
    @PostMapping("/downCopy")
    public AjaxResult downCopy(@RequestBody ProductModelDto productModelDto) {
        return toAjax(productModelService.downCopy(productModelDto));
    }
}
src/main/java/com/ruoyi/basic/dto/ProductModelDto.java
@@ -9,4 +9,10 @@
@Data
public class ProductModelDto extends ProductModel {
    private List<ProductStructureDto> productStructureList;
    //复制的目标产品id
    private Long targetProductId;
    //型号list
    private List<Long> modelListId;
}
src/main/java/com/ruoyi/basic/service/IProductModelService.java
@@ -35,4 +35,6 @@
    IPage<ProductModel> modelListPage(Page page , ProductDto productDto);
    AjaxResult importProductModel(MultipartFile file, Integer productId);
    int downCopy(ProductModelDto productModelDto);
}
src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
@@ -155,4 +155,60 @@
            throw new ServiceException("导入失败");
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int downCopy(ProductModelDto productModelDto) {
        if (productModelDto == null || productModelDto.getProductId() == null || productModelDto.getTargetProductId() == null) {
            throw new ServiceException("源产品ID和目标产品ID不能为空");
        }
        Long sourceProductId = productModelDto.getProductId();
        Long targetProductId = productModelDto.getTargetProductId();
        List<Long> modelListId = productModelDto.getModelListId();
        if (sourceProductId.equals(targetProductId)) {
            throw new ServiceException("源产品和目标产品不能相同");
        }
        Product sourceProduct = productMapper.selectById(sourceProductId);
        if (sourceProduct == null) {
            throw new ServiceException("源产品不存在");
        }
        Product targetProduct = productMapper.selectById(targetProductId);
        if (targetProduct == null) {
            throw new ServiceException("目标产品不存在");
        }
        LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<ProductModel>()
                .eq(ProductModel::getProductId, sourceProductId)
                .orderByAsc(ProductModel::getId);
        Set<Long> selectedModelIds = null;
        if (CollectionUtils.isNotEmpty(modelListId)) {
            selectedModelIds = new LinkedHashSet<>(modelListId);
            queryWrapper.in(ProductModel::getId, selectedModelIds);
        }
        List<ProductModel> sourceModels = productModelMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(sourceModels)) {
            throw new ServiceException("源产品下没有可复制的型号");
        }
        if (selectedModelIds != null && sourceModels.size() != selectedModelIds.size()) {
            throw new ServiceException("部分型号不存在或不属于源产品");
        }
        List<ProductModel> copyList = new ArrayList<>();
        for (ProductModel sourceModel : sourceModels) {
            ProductModel copy = new ProductModel();
            BeanUtils.copyProperties(sourceModel, copy);
            copy.setId(null);
            copy.setProductId(targetProductId);
            copy.setTenantId(null);
            copyList.add(copy);
        }
        saveBatch(copyList);
        return copyList.size();
    }
}
src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -88,5 +88,5 @@
    private String batchNo;
    @ApiModelProperty(value = "产品结构投入数量")
    private BigDecimal bomInputQty;
    private BigDecimal inputWeight;
}
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -1,5 +1,8 @@
package com.ruoyi.production.service.impl;
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.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -52,6 +55,8 @@
    private static final String PROCESS_VOLTAGE_SORT = "电压分选";
    private static final String PROCESS_OPTICAL_INSPECTION = "光检外观";
    private static final String PROCESS_PACKAGING = "包装";
    private static final String INPUT_WEIGHT_PARAMETER = "投入重量";
    private static final String INPUT_WEIGHT_FIELD = "inputWeight";
    private static final Object PRODUCT_MAIN_NO_LOCK = new Object();
    private IQualityInspectService qualityInspectService;
@@ -98,7 +103,10 @@
        BigDecimal reportQty = dto.getQuantity();
        BigDecimal scrapQty = dto.getScrapQty() == null ? BigDecimal.ZERO : dto.getScrapQty();
        BigDecimal bomInputQty = dto.getBomInputQty();
        BigDecimal bomInputQty = dto.getInputWeight();
        if (bomInputQty == null) {
            bomInputQty = resolveInputWeight(dto.getOtherData());
        }
        if (reportQty == null || reportQty.compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("报工数量必须大于0");
        }
@@ -345,7 +353,7 @@
            ProductionProductInput productionProductInput = new ProductionProductInput();
            productionProductInput.setProductModelId(productStructureDto.getProductModelId());
            productionProductInput.setQuantity(needQty);
            productionProductInput.setQuantity(needQty == null ? BigDecimal.ZERO : needQty);
            productionProductInput.setProductMainId(productionProductMain.getId());
            productionProductInputMapper.insert(productionProductInput);
@@ -761,4 +769,87 @@
        return productionProductMainDtos;
    }
    private BigDecimal resolveInputWeight(String otherData) {
        if (StringUtils.isBlank(otherData)) {
            return null;
        }
        Object parsed;
        try {
            parsed = JSON.parse(otherData);
        } catch (Exception ex) {
            throw new ServiceException("报工参数格式错误,无法解析投入重量");
        }
        String inputWeight = StringUtils.trim(findParameterValue(parsed, INPUT_WEIGHT_PARAMETER));
        if (StringUtils.isBlank(inputWeight)) {
            inputWeight = StringUtils.trim(findFieldValue(parsed, INPUT_WEIGHT_FIELD));
        }
        if (StringUtils.isBlank(inputWeight)) {
            return null;
        }
        try {
            return new BigDecimal(inputWeight);
        } catch (NumberFormatException ex) {
            throw new ServiceException("报工参数中的投入重量格式错误");
        }
    }
    private String findParameterValue(Object node, String parameterItem) {
        if (node instanceof JSONArray) {
            JSONArray array = (JSONArray) node;
            for (Object item : array) {
                String value = findParameterValue(item, parameterItem);
                if (StringUtils.isNotBlank(value)) {
                    return value;
                }
            }
            return null;
        }
        if (node instanceof JSONObject) {
            JSONObject object = (JSONObject) node;
            if (parameterItem.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 matched = findParameterValue(value, parameterItem);
                if (StringUtils.isNotBlank(matched)) {
                    return matched;
                }
            }
        }
        return null;
    }
    private String findFieldValue(Object node, String fieldName) {
        if (node instanceof JSONArray) {
            JSONArray array = (JSONArray) node;
            for (Object item : array) {
                String value = findFieldValue(item, fieldName);
                if (StringUtils.isNotBlank(value)) {
                    return value;
                }
            }
            return null;
        }
        if (node instanceof JSONObject) {
            JSONObject object = (JSONObject) node;
            Object fieldValue = object.get(fieldName);
            if (fieldValue != null) {
                String value = StringUtils.trim(String.valueOf(fieldValue));
                if (StringUtils.isNotBlank(value)) {
                    return value;
                }
            }
            for (Object value : object.values()) {
                String matched = findFieldValue(value, fieldName);
                if (StringUtils.isNotBlank(matched)) {
                    return matched;
                }
            }
        }
        return null;
    }
}
src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
@@ -1,32 +1,22 @@
package com.ruoyi.sales.controller;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
import com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.sales.dto.SalesLedgerProductDto;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;
@@ -38,8 +28,7 @@
 */
@RestController
@RequestMapping("/sales/product")
public class SalesLedgerProductController extends BaseController
{
public class SalesLedgerProductController extends BaseController {
    @Autowired
    private ISalesLedgerProductService salesLedgerProductService;
    @Autowired
@@ -53,7 +42,7 @@
     */
    @GetMapping("/listPageSalesLedger")
    public AjaxResult listPage(Page page, SalesLedgerProductDto salesLedgerProduct) {
        IPage<SalesLedgerProductDto> list = salesLedgerProductService.listPage(page,salesLedgerProduct);
        IPage<SalesLedgerProductDto> list = salesLedgerProductService.listPage(page, salesLedgerProduct);
        return AjaxResult.success(list);
    }
@@ -63,7 +52,7 @@
     */
    @GetMapping("/listPagePurchaseLedger")
    public AjaxResult listPagePurchaseLedger(Page page, SalesLedgerProductDto salesLedgerProduct) {
        IPage<SalesLedgerProductDto> list = salesLedgerProductService.listPagePurchaseLedger(page,salesLedgerProduct);
        IPage<SalesLedgerProductDto> list = salesLedgerProductService.listPagePurchaseLedger(page, salesLedgerProduct);
        return AjaxResult.success(list);
    }
@@ -104,8 +93,7 @@
     */
    @Log(title = "产品信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SalesLedgerProduct salesLedgerProduct)
    {
    public void export(HttpServletResponse response, SalesLedgerProduct salesLedgerProduct) {
        List<SalesLedgerProduct> list = salesLedgerProductService.selectSalesLedgerProductList(salesLedgerProduct);
        ExcelUtil<SalesLedgerProduct> util = new ExcelUtil<SalesLedgerProduct>(SalesLedgerProduct.class);
        util.exportExcel(response, list, "产品信息数据");
@@ -115,8 +103,7 @@
     * 获取产品信息详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(salesLedgerProductService.selectSalesLedgerProductById(id));
    }
@@ -124,9 +111,8 @@
     * 新增修改产品信息
     */
    @Log(title = "产品信息", businessType = BusinessType.INSERT)
    @PostMapping  ("/addOrUpdateSalesLedgerProduct")
    public AjaxResult add(@RequestBody SalesLedgerProduct salesLedgerProduct)
    {
    @PostMapping("/addOrUpdateSalesLedgerProduct")
    public AjaxResult add(@RequestBody SalesLedgerProduct salesLedgerProduct) {
        return toAjax(salesLedgerProductService.addOrUpdateSalesLedgerProduct(salesLedgerProduct));
    }
@@ -134,9 +120,8 @@
     * 删除产品信息
     */
    @Log(title = "产品信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/delProduct")
    public AjaxResult remove(@RequestBody Long[] ids)
    {
    @DeleteMapping("/delProduct")
    public AjaxResult remove(@RequestBody Long[] ids) {
        if (ids == null || ids.length == 0) {
            return AjaxResult.error("请传入要删除的ID");
        }
@@ -146,6 +131,11 @@
    //根据产品id获取bom判断库存是否充足
    @GetMapping("/judgmentInventory")
    public R judgmentInventory(SalesLedgerProduct salesLedgerProduct) {
        return  salesLedgerProductService.judgmentInventory(salesLedgerProduct);
        return salesLedgerProductService.judgmentInventory(salesLedgerProduct);
    }
    @GetMapping("/getById")
    public R getById(SalesLedgerProduct salesLedgerProduct) {
        return R.ok(salesLedgerProductService.getById(salesLedgerProduct));
    }
}
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
@@ -1,12 +1,9 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -15,22 +12,14 @@
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.sales.dto.ShippingInfoDto;
import com.ruoyi.sales.mapper.ShipmentApprovalMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShipmentApproval;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import com.ruoyi.sales.service.ShippingInfoService;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
@@ -64,7 +53,7 @@
    @GetMapping("/listPage")
    @ApiOperation("发货信息列表")
    public AjaxResult listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfoDto> listPage = shippingInfoService.listPage(page,req);
        IPage<ShippingInfoDto> listPage = shippingInfoService.listPage(page, req);
        return AjaxResult.success(listPage);
    }
@@ -79,10 +68,13 @@
        ApproveProcessVO approveProcessVO = new ApproveProcessVO();
        approveProcessVO.setApproveType(7);
        approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
        approveProcessVO.setApproveReason(req.getType() + ":" +sh);
        approveProcessVO.setApproveReason(req.getType() + ":" + sh);
        approveProcessVO.setApproveUserIds(req.getApproveUserIds());
        approveProcessVO.setApproveUser(loginUser.getUserId());
        approveProcessVO.setApproveTime(LocalDate.now().toString());
        if (req.getSalesLedgerProductId() != null) {
            approveProcessVO.setRecordId(req.getSalesLedgerProductId());
        }
        approveProcessService.addApprove(approveProcessVO);
        // 添加发货消息
        req.setShippingNo(sh);
@@ -96,7 +88,7 @@
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.UPDATE)
    public AjaxResult deductStock(@RequestBody ShippingInfoDto req) throws IOException {
        return shippingInfoService.deductStock( req) ? AjaxResult.success() : AjaxResult.error();
        return shippingInfoService.deductStock(req) ? AjaxResult.success() : AjaxResult.error();
    }
    @PostMapping("/update")
src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java
@@ -1,10 +1,8 @@
package com.ruoyi.sales.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.ShippingInfo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -263,6 +263,11 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) {
        if (stockInventoryDto.getQualitity() != null
                && stockInventoryDto.getQualitity().compareTo(BigDecimal.ZERO) == 0) {
            return true;
        }
        StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
        stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId());
        stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType());
@@ -298,7 +303,7 @@
                throw new RuntimeException("产品库存不存在");
            }
            BigDecimal remainingQty = stockInventoryDto.getQualitity();
            BigDecimal remainingQty = stockInventoryDto.getQualitity() == null ? BigDecimal.ZERO : stockInventoryDto.getQualitity();
            for (StockInventory stockInventory : stockInventories) {
                BigDecimal lockedQty = defaultDecimal(stockInventory.getLockedQuantity());
                BigDecimal availableQty = defaultDecimal(stockInventory.getQualitity()).subtract(lockedQty);
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml
@@ -89,7 +89,7 @@
            </if>
        </where>
        GROUP BY slpa.scheduling_user_name
        GROUP BY slpa.scheduling_user_id, slpa.scheduling_user_name
    </select>
src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -48,7 +48,7 @@
        <if test="qualityInspect.entryDateEnd != null and qualityInspect.entryDateEnd != '' ">
            AND qi.check_time &lt;= DATE_FORMAT(#{qualityInspect.entryDateEnd},'%Y-%m-%d')
        </if>
        ORDER BY qi.check_time DESC
        ORDER BY qi.create_time DESC
    </select>
    <select id="qualityInspectExport" resultType="com.ruoyi.quality.pojo.QualityInspect">
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -203,6 +203,7 @@
            </if>
        </where>
        group by product_model_id, model, unit, product_name, product_id, unQualifiedBatchNo, materialCode, processCategory, voltage
        having SUM(qualifiedQuantity) > 0 or SUM(unQualifiedQuantity) > 0
    </select>
    <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
@@ -296,6 +297,7 @@
            </if>
        </where>
        group by product_model_id, model, unit, product_name, unQualifiedBatchNo, materialCode, processCategory, voltage
        having SUM(qualifiedQuantity) > 0 or SUM(unQualifiedQuantity) > 0
    </select>
    <select id="stockInventoryPage" resultType="com.ruoyi.stock.dto.StockInRecordDto">
        select sir.*,si.qualitity as current_stock,