liyong
8 天以前 6f287ccb0f8df857fbce894bd241cdf77690cecb
Merge branch 'jtwy' of http://114.132.189.42:9002/r/product-inventory-management-after into sqd-hb
已添加2个文件
已修改33个文件
1105 ■■■■■ 文件已修改
doc/20260119-procurement_record_storage.sql 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/ProductModel.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/dto/ProductionProgressDto.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/dto/ProductionTurnoverDto.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductBomController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/SalesLedgerProductionAccountingController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProcessRouteService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java 152 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java 177 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 247 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/ProductModelMapper.xml 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductStructureMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductWorkOrderMapper.xml 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductInputMapper.xml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductMainMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260119-procurement_record_storage.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
alter table procurement_record_storage
    add quality_inspect_id bigint null comment '质检id';
src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
import org.apache.ibatis.annotations.Param;
@@ -17,6 +18,8 @@
    IPage<ProductModel> listPageProductModel(Page<ProductModel> page, @Param("c") ProductModel productModel);
    IPage<ProductModel> listPageProductionStock(Page<ProductModel> page, @Param("req") ProcurementPageDto req);
    ProductModel selectLatestRecord();
}
src/main/java/com/ruoyi/basic/pojo/ProductModel.java
@@ -6,6 +6,7 @@
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@TableName("product_model")
@@ -59,4 +60,7 @@
    @TableField(exist = false)
    @Excel(name = "剩余库存")
    private BigDecimal stockQuantity;
    @TableField(exist = false)
    private LocalDateTime createTime;
}
src/main/java/com/ruoyi/home/dto/ProductionProgressDto.java
@@ -12,14 +12,14 @@
@ApiModel
public class ProductionProgressDto {
    @ApiModelProperty("总订单数")
    private Integer totalOrderCount;
    private Long totalOrderCount;
    @ApiModelProperty("已完成订单数")
    private Integer completedOrderCount;
    private Long completedOrderCount;
    @ApiModelProperty("未完成订单数")
    private Integer uncompletedOrderCount;
    @ApiModelProperty("总体完成进度")
    private BigDecimal completedProgressCount;
    private Long uncompletedOrderCount;
    @ApiModelProperty("部分完成订单数")
    private Long partialCompletedOrderCount;
    @ApiModelProperty("订单详情")
    private List<ProductOrderDto> completedOrderDetails;
}
src/main/java/com/ruoyi/home/dto/ProductionTurnoverDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.home.dto;
import com.ruoyi.production.dto.ProductOrderDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@ApiModel
public class ProductionTurnoverDto {
    @ApiModelProperty("总在制数量")
    private Long totalOrderCount;
    @ApiModelProperty("平均周转天数")
    private BigDecimal averageTurnoverDays;
    @ApiModelProperty("周转效率")
    private BigDecimal turnoverEfficiency;
    @ApiModelProperty("工序详情")
    private List<String> processDetails;
    @ApiModelProperty("工序对应的数量详情")
    private List<Long> processQuantityDetails;
}
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -235,8 +235,8 @@
    @GetMapping("/listPageProductionStock")
    @Log(title = "库存管理-成品库存", businessType = BusinessType.OTHER)
    public AjaxResult listPageProductionStock(Page page) {
        IPage<ProductModel> result = procurementRecordService.listPageProductionStock(page);
    public AjaxResult listPageProductionStock(Page page, ProcurementPageDto procurementDto) {
        IPage<ProductModel> result = procurementRecordService.listPageProductionStock(page,procurementDto);
        return AjaxResult.success(result);
    }
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java
@@ -22,6 +22,7 @@
    private String typeName;
    private Integer purchaseLedgerId;
    private Long qualityInspectId;
    private Long qualityInspectId;
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
@@ -101,6 +101,5 @@
     */
    private Long productModelId;
    private Long qualityInspectId;
}
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
@@ -60,7 +60,7 @@
    BigDecimal getProcurementAmount(Long salesProductId);
    InventoryInformationDto getReportList();
    IPage<ProductModel> listPageProductionStock(Page page);
    IPage<ProductModel> listPageProductionStock(Page page, ProcurementPageDto procurementDto);
    IPage<ProcurementPageDto> listPageByProductProduction(Page page, ProcurementPageDto procurementDto);
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -62,13 +62,13 @@
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = procurementDtos.stream().map(ProcurementDto::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
        if(CollectionUtils.isEmpty( collect)){
            return procurementDtos;
        }
        LambdaQueryWrapper<ProcurementRecordStorage> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordStorage::getSalesLedgerProductId, collect);
        List<ProcurementRecordStorage> procurementRecordStorages = procurementRecordMapper.selectList(procurementRecordLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(procurementRecordStorages)) {
        if(CollectionUtils.isEmpty(procurementRecordStorages)){
            return procurementDtos;
        }
        for (ProcurementDto dto : procurementDtos) {
@@ -78,7 +78,7 @@
                    .collect(Collectors.toList());
            // å¦‚果没有相关的入库记录,跳过该条数据
            if (CollectionUtils.isEmpty(collect1)) {
            if(CollectionUtils.isEmpty(collect1)){
                dto.setQuantity0(dto.getQuantity());
                continue;
            }
@@ -129,9 +129,9 @@
        // åˆ é™¤æ‰€æœ‰å¯¹åº”的出库记录
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordOutLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordOutLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, procurementDto.getIds())
                .eq(ProcurementRecordOut::getType, procurementDto.getType());
                .eq(ProcurementRecordOut::getType,procurementDto.getType());
        List<ProcurementRecordOut> procurementRecordOuts = procurementRecordOutMapper.selectList(procurementRecordOutLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(procurementRecordOuts)) {
        if(!CollectionUtils.isEmpty(procurementRecordOuts)){
            procurementRecordOutMapper.deleteBatchIds(procurementRecordOuts.stream().map(ProcurementRecordOut::getId).collect(Collectors.toList()));
        }
        return 0;
@@ -388,7 +388,7 @@
            currentStock += dto.getInboundNum().intValue() - totalInboundNum.intValue();
            values.add(currentStock);
            // è®¡ç®—周转率
            if (totalIn > 0) {
            if(totalIn > 0){
                turnoverRate = totalOut * 100 / totalIn;
            }
        }
@@ -766,7 +766,7 @@
                    .eq(ProcurementRecordStorage::getType, procurementDto.getType());
            Long aLong = procurementRecordMapper.selectCount(procurementRecordLambdaQueryWrapper);
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(detail.getId());
            if (ObjectUtils.isNull(detail.getProductModelId())) {
            if (ObjectUtils.isNull(detail.getProductModelId())){
                detail.setProductModelId(salesLedgerProduct.getProductModelId());
            }
            ProcurementRecordStorage.ProcurementRecordStorageBuilder procurementRecordBuilder = ProcurementRecordStorage.builder()
@@ -783,7 +783,7 @@
                    .updateUser(loginUser.getUserId())
                    .createBy(procurementDto.getNickName())
                    .productModelId(detail.getProductModelId())
                    .qualityInspectId(ObjectUtils.isNotNull(procurementDto.getQualityInspectId()) ? procurementDto.getQualityInspectId() : 0L);
                    .qualityInspectId(ObjectUtils.isNotNull(procurementDto.getQualityInspectId())?procurementDto.getQualityInspectId():0L);
            this.save(procurementRecordBuilder.build());
            // å…¥åº“成功减掉采购数量
//            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -805,14 +805,14 @@
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = procurementPageDtos.stream().map(ProcurementPageDto::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
        if(CollectionUtils.isEmpty( collect)){
            return procurementPageDtoIPage;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect)
                .eq(ProcurementRecordOut::getType, 1);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(procurementRecords)) {
        if(CollectionUtils.isEmpty( procurementRecords)){
            return procurementPageDtoIPage;
        }
        for (ProcurementPageDto dto : procurementPageDtos) {
@@ -822,7 +822,7 @@
                    .collect(Collectors.toList());
            // å¦‚果没有相关的出库记录,跳过该条数据
            if (CollectionUtils.isEmpty(collect1)) {
            if(CollectionUtils.isEmpty(collect1)){
                dto.setInboundNum0(dto.getInboundNum());
                continue;
            }
@@ -845,14 +845,14 @@
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = procurementPageDtoCopyList.stream().map(ProcurementPageDtoCopy::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
        if(CollectionUtils.isEmpty( collect)){
            return procurementPageDtoCopyIPage;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect);
        procurementRecordLambdaQueryWrapper.eq(ProcurementRecordOut::getType, 1);
        procurementRecordLambdaQueryWrapper.eq(ProcurementRecordOut::getType,1);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(procurementRecords)) {
        if(CollectionUtils.isEmpty( procurementRecords)){
            return procurementPageDtoCopyIPage;
        }
        for (ProcurementPageDtoCopy dto : procurementPageDtoCopyList) {
@@ -862,7 +862,7 @@
                    .collect(Collectors.toList());
            // å¦‚果没有相关的出库记录,跳过该条数据
            if (CollectionUtils.isEmpty(collect1)) {
            if(CollectionUtils.isEmpty(collect1)){
                dto.setInboundNum0(dto.getInboundNum());
                dto.setTotalInboundNum(BigDecimal.ZERO);
                continue;
@@ -877,7 +877,7 @@
            // å¾…出库数量 = æ€»æ•°é‡ - å·²å‡ºåº“数量
            dto.setInboundNum0(dto.getInboundNum().subtract(totalInboundNum));
            // åº“存价值
            if (dto.getUnitPrice() != null) {
            if(dto.getUnitPrice() != null){
                dto.setTotalPrice(dto.getInboundNum0().multiply(dto.getUnitPrice()));
            }
        }
@@ -885,15 +885,8 @@
    }
    @Override
    public IPage<ProductModel> listPageProductionStock(Page page) {
        ProductModel productModel = new ProductModel();
        IPage<ProductModel> iPage = productModelMapper.listPageProductModel(page, productModel);
        iPage.getRecords().forEach(item -> {
            item.setInboundNum(stockUtils.getStockQuantity(item.getId()).get("inboundNum"));
            item.setOutboundNum(stockUtils.getStockQuantity(item.getId()).get("outboundNum"));
            item.setStockQuantity(stockUtils.getStockQuantity(item.getId()).get("stockQuantity"));
        });
        return iPage;
    public IPage<ProductModel> listPageProductionStock(Page page, ProcurementPageDto dto) {
        return productModelMapper.listPageProductionStock(page, dto);
    }
@@ -906,14 +899,14 @@
        // è®¡ç®—待入库数量
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = procurementPageDtos.stream().map(ProcurementPageDto::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
        if(CollectionUtils.isEmpty( collect)){
            return procurementPageDtoIPage;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect)
                .eq(ProcurementRecordOut::getType, 4);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(procurementRecords)) {
        if(CollectionUtils.isEmpty( procurementRecords)){
            return procurementPageDtoIPage;
        }
        for (ProcurementPageDto dto : procurementPageDtos) {
@@ -923,7 +916,7 @@
                    .collect(Collectors.toList());
            // å¦‚果没有相关的出库记录,跳过该条数据
            if (CollectionUtils.isEmpty(collect1)) {
            if(CollectionUtils.isEmpty(collect1)){
                dto.setInboundNum0(dto.getInboundNum());
                continue;
            }
src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -9,10 +9,12 @@
import com.ruoyi.production.dto.ProductBomDto;
import com.ruoyi.production.pojo.ProcessRoute;
import com.ruoyi.production.pojo.ProductBom;
import com.ruoyi.production.pojo.ProductProcess;
import com.ruoyi.production.pojo.ProductProcessRoute;
import com.ruoyi.production.service.ProcessRouteService;
import com.ruoyi.production.service.ProductBomService;
import com.ruoyi.production.service.ProductProcessRouteService;
import com.ruoyi.production.service.ProductProcessService;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
@@ -4,6 +4,7 @@
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.dto.ProductionProductMainDto;
import com.ruoyi.production.dto.SalesLedgerProductionAccountingDto;
import com.ruoyi.production.service.ProductionProductMainService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -12,6 +13,7 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
@RequestMapping("productionProductMain")
src/main/java/com/ruoyi/production/controller/SalesLedgerProductionAccountingController.java
@@ -2,11 +2,13 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.pojo.AccountExpense;
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.production.dto.ProductOrderDto;
import com.ruoyi.production.dto.SalesLedgerProductionAccountingDto;
import com.ruoyi.production.service.impl.SalesLedgerProductionAccountingServiceImpl;
import io.swagger.annotations.Api;
src/main/java/com/ruoyi/production/service/ProcessRouteService.java
@@ -8,6 +8,8 @@
import java.util.List;
import java.util.List;
public interface ProcessRouteService extends IService<ProcessRoute> {
    IPage<ProcessRouteDto> pageProcessRouteDto(Page<ProcessRouteDto> page, ProcessRouteDto processRouteDto);
src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
@@ -8,9 +8,14 @@
import com.ruoyi.production.mapper.ProcessRouteItemMapper;
import com.ruoyi.production.mapper.ProcessRouteMapper;
import com.ruoyi.production.mapper.ProductOrderMapper;
import com.ruoyi.production.mapper.ProductOrderMapper;
import com.ruoyi.production.mapper.ProductProcessRouteMapper;
import com.ruoyi.production.pojo.ProcessRoute;
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.pojo.ProductProcessRoute;
import com.ruoyi.production.service.ProcessRouteService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -20,6 +25,8 @@
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Arrays;
import java.util.List;
@Service
@AllArgsConstructor
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -32,6 +32,8 @@
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.production.mapper.ProductionProductMainMapper;
import oshi.driver.mac.net.NetStat;
import java.math.BigDecimal;
import java.time.LocalDate;
src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
@@ -24,6 +25,7 @@
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@@ -192,15 +194,27 @@
     */
    @GetMapping("/listPage")
    public AjaxResult listPage(Page page, PurchaseLedgerDto purchaseLedger) {
        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerService.selectPurchaseLedgerListPage(page ,purchaseLedger);
        //过滤掉approvalStatus=3的记录
        purchaseLedgerDtoIPage.getRecords().removeIf(purchaseLedgerDto -> purchaseLedgerDto.getApprovalStatus() == 3);
        purchaseLedgerDtoIPage.getRecords().forEach(purchaseLedgerDto -> {
            if (purchaseLedgerDto.getUnReceiptPaymentAmount().compareTo(BigDecimal.ZERO) == 0) {
                purchaseLedgerDto.setUnReceiptPaymentAmount(purchaseLedgerDto.getContractAmount());
            }
        });
         return AjaxResult.success(purchaseLedgerDtoIPage);
        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = Optional.ofNullable(
                purchaseLedgerService.selectPurchaseLedgerListPage(page, purchaseLedger)
        ).orElse(new Page<>());
        // å¤„理null
        Optional.ofNullable(purchaseLedgerDtoIPage.getRecords())
                .filter(CollectionUtils::isNotEmpty)
                .ifPresent(records -> {
                    // è¿‡æ»¤approvalStatus=3的记录
                    records.removeIf(dto -> dto != null && dto.getApprovalStatus() == 3);
                    // ä¿®æ­£æœªæ”¶ä»˜æ¬¾é‡‘额
                    records.forEach(dto -> {
                        if (dto == null) return;
                        BigDecimal unReceiptAmt = Optional.ofNullable(dto.getUnReceiptPaymentAmount()).orElse(BigDecimal.ZERO);
                        if (unReceiptAmt.compareTo(BigDecimal.ZERO) == 0) {
                            dto.setUnReceiptPaymentAmount(Optional.ofNullable(dto.getContractAmount()).orElse(BigDecimal.ZERO));
                        }
                    });
                });
        return AjaxResult.success(purchaseLedgerDtoIPage);
    }
    @ApiOperation("生成采购序列号")
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -24,6 +24,8 @@
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.purchase.dto.PurchaseLedgerDto;
@@ -111,6 +113,7 @@
    private final QualityTestStandardMapper qualityTestStandardMapper;
    private final QualityInspectParamMapper qualityInspectParamMapper;
    private final ProcurementRecordMapper procurementRecordStorageMapper;
    @Value("${file.upload-dir}")
    private String uploadDir;
@@ -238,10 +241,12 @@
            handleSalesLedgerProducts(purchaseLedger.getId(), productList, purchaseLedgerDto.getType());
        }
        //新增原材料检验
        for (SalesLedgerProduct saleProduct : productList) {
            //是否推送质检,如果true就添加
            if (saleProduct.getIsChecked()) {
                addQualityInspect(purchaseLedger, saleProduct);
        if (productList != null) {
            for (SalesLedgerProduct saleProduct : productList) {
                //是否推送质检,如果true就添加
                if (saleProduct.getIsChecked()) {
                    addQualityInspect(purchaseLedger, saleProduct);
                }
            }
        }
        // 5. è¿ç§»ä¸´æ—¶æ–‡ä»¶åˆ°æ­£å¼ç›®å½•
@@ -256,8 +261,8 @@
        QualityInspect qualityInspect = new QualityInspect();
        qualityInspect.setInspectType(0);
        qualityInspect.setSupplier(purchaseLedger.getSupplierName());
        qualityInspect.setPurchaseLedgerId(purchaseLedger.getId());
        qualityInspect.setProductId(saleProduct.getId());
        qualityInspect.setPurchaseLedgerId(saleProduct.getId());
        qualityInspect.setProductId(saleProduct.getProductId());
        qualityInspect.setProductName(saleProduct.getProductCategory());
        qualityInspect.setModel(saleProduct.getSpecificationModel());
        qualityInspect.setProductModelId(saleProduct.getProductModelId());
@@ -445,6 +450,19 @@
        if (ids == null || ids.length == 0) {
           throw new BaseException("请选中至少一条数据");
        }
        // æ‰¹é‡åˆ é™¤å…³è”的采购入库记录
        LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductQueryWrapper = new LambdaQueryWrapper<>();
        salesLedgerProductQueryWrapper.in(SalesLedgerProduct::getSalesLedgerId, ids)
                .eq(SalesLedgerProduct::getType, 2);
        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(salesLedgerProductQueryWrapper);
        if (CollectionUtils.isNotEmpty(salesLedgerProducts)) {
            salesLedgerProducts.stream().forEach(salesLedgerProduct -> {
                // æ‰¹é‡åˆ é™¤å…³è”的采购台账产品
                LambdaQueryWrapper<ProcurementRecordStorage> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ProcurementRecordStorage::getSalesLedgerProductId, salesLedgerProduct.getId());
                procurementRecordStorageMapper.delete(queryWrapper);
            });
        }
        // æ‰¹é‡åˆ é™¤å…³è”的采购台账产品
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, ids)
src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.purchase.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
@@ -29,6 +30,7 @@
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import lombok.RequiredArgsConstructor;
@@ -48,10 +50,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@@ -163,6 +162,14 @@
                    productRecord.setPurchaseLedgerId(ticketRegistrationDto.getPurchaseLedgerId());
                    productRecord.setCreatedAt(DateUtils.getNowDate());
                    BeanUtils.copyProperties(salesLedgerProduct, productRecord);
                    //同步更新其他剩余数量和金额
                    productRecordMapper.update(
                            null,
                            new LambdaUpdateWrapper<ProductRecord>()
                                    .eq(ProductRecord::getPurchaseLedgerId, ticketRegistrationDto.getPurchaseLedgerId())
                                    .set(ProductRecord::getFutureTickets, salesLedgerProduct.getFutureTickets())
                                    .set(ProductRecord::getFutureTicketsAmount, salesLedgerProduct.getFutureTicketsAmount())
                    );
                    productRecord.setSaleLedgerProjectId(salesLedgerProduct.getId());
                    productRecord.setId(null);
                    productRecord.setType("2");
@@ -249,50 +256,119 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delRegistration(Long[] ids) {
        // åˆ é™¤é‡‡è´­å°è´¦äº§å“å¼€ç¥¨è®°å½•对象
        LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productRecordLambdaQueryWrapper.in(ProductRecord::getId, Arrays.asList(ids));
        List<ProductRecord> productRecords = productRecordMapper.selectList(productRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty(productRecords)){
        //  æŸ¥è¯¢è¦åˆ é™¤çš„产品来票记录
        LambdaQueryWrapper<ProductRecord> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.in(ProductRecord::getId, Arrays.asList(ids));
        List<ProductRecord> productRecords = productRecordMapper.selectList(productWrapper);
        if (CollectionUtils.isEmpty(productRecords)) {
            return 0;
        }
        LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getId, productRecords.stream().map(ProductRecord::getTicketRegistrationId).collect(Collectors.toList()));
        List<TicketRegistration> ticketRegistrations = ticketRegistrationMapper.selectList(ticketRegistrationLambdaQueryWrapper);
        // ä¿®æ”¹äº§å“ä¿¡æ¯
        for (ProductRecord productRecord : productRecords) {
            BigDecimal subtract = ticketRegistrations.get(0).getInvoiceAmount().subtract(productRecords.get(0).getTicketsAmount());
            // å°äºŽç­‰äºŽ0删除 ï¼Œå¤§äºŽ0修改
            if(subtract.compareTo(BigDecimal.ZERO) <= 0){
                ticketRegistrationMapper.deleteById(ticketRegistrations.get(0));
                // åˆ é™¤ä»˜æ¬¾æµæ°´è®°å½•
                paymentRegistrationMapper.delete(new LambdaQueryWrapper<PaymentRegistration>().eq(PaymentRegistration::getTicketRegistrationId, ticketRegistrations.get(0).getId()));
            }else if(subtract.compareTo(BigDecimal.ZERO) > 0){
                ticketRegistrations.get(0).setInvoiceAmount(subtract);
                ticketRegistrationMapper.updateById(ticketRegistrations.get(0));
            }
            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
            salesLedgerProductLambdaQueryWrapper.eq(SalesLedgerProduct::getId, productRecord.getSaleLedgerProjectId())
                    .eq(SalesLedgerProduct::getType, 2);
            List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(salesLedgerProductLambdaQueryWrapper);
            if(!CollectionUtils.isEmpty(salesLedgerProducts)){
                for (SalesLedgerProduct salesLedgerProduct : salesLedgerProducts) {
                    salesLedgerProduct.setFutureTickets(salesLedgerProduct.getFutureTickets().add(productRecord.getTicketsNum()));
                    salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getFutureTicketsAmount().add(productRecord.getTicketsAmount()));
                    salesLedgerProduct.setTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(salesLedgerProduct.getFutureTicketsAmount()));
                    salesLedgerProduct.setTicketsNum(salesLedgerProduct.getQuantity().subtract(salesLedgerProduct.getFutureTickets()));
                    salesLedgerProductMapper.updateById(salesLedgerProduct);
        //  æ”¶é›†å…³è”ID
        Set<Long> ticketRegistrationIds = productRecords.stream()
                .map(ProductRecord::getTicketRegistrationId)
                .collect(Collectors.toSet());
                }
        Set<Long> salesLedgerProductIds = productRecords.stream()
                .map(ProductRecord::getSaleLedgerProjectId)
                .collect(Collectors.toSet());
        //  æŸ¥è¯¢æ¥ç¥¨ç™»è®°
        List<TicketRegistration> ticketRegistrations =
                ticketRegistrationMapper.selectBatchIds(ticketRegistrationIds);
        //  å¤„理来票登记金额、付款流水
        for (TicketRegistration ticket : ticketRegistrations) {
            // è¯¥æ¥ç¥¨ç™»è®°ä¸‹æ‰€æœ‰äº§å“è®°å½•
            List<ProductRecord> recordsOfTicket = productRecords.stream()
                    .filter(r -> r.getTicketRegistrationId().equals(ticket.getId()))
                    .collect(Collectors.toList());
            // è®¡ç®—要回退的金额
            BigDecimal rollbackAmount = recordsOfTicket.stream()
                    .map(ProductRecord::getTicketsAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal remain = ticket.getInvoiceAmount().subtract(rollbackAmount);
            if (remain.compareTo(BigDecimal.ZERO) <= 0) {
                // åˆ é™¤æ¥ç¥¨ç™»è®°
                ticketRegistrationMapper.deleteById(ticket.getId());
                // åˆ é™¤ä»˜æ¬¾æµæ°´
                paymentRegistrationMapper.delete(
                        new LambdaQueryWrapper<PaymentRegistration>()
                                .eq(PaymentRegistration::getTicketRegistrationId, ticket.getId())
                );
            } else {
                ticket.setInvoiceAmount(remain);
                ticketRegistrationMapper.updateById(ticket);
            }
        }
        // åˆ é™¤é‡‡è´­å°è´¦äº§å“å¼€ç¥¨è®°å½•
        productRecordMapper.delete(productRecordLambdaQueryWrapper);
        //  å›žé€€é”€å”®å°è´¦äº§å“çš„æœªæ¥ç¥¨
        for (ProductRecord record : productRecords) {
            LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SalesLedgerProduct::getId, record.getSaleLedgerProjectId())
                    .eq(SalesLedgerProduct::getType, 2);
            SalesLedgerProduct product = salesLedgerProductMapper.selectOne(wrapper);
            if (product != null) {
                product.setFutureTickets(
                        product.getFutureTickets().add(record.getTicketsNum())
                );
                product.setFutureTicketsAmount(
                        product.getFutureTicketsAmount().add(record.getTicketsAmount())
                );
                salesLedgerProductMapper.updateById(product);
            }
        }
        //  åˆ é™¤äº§å“æ¥ç¥¨è®°å½•
        productRecordMapper.delete(productWrapper);
        //  é‡æ–°è®¡ç®— currentInvoiceAmount
        for (Long productId : salesLedgerProductIds) {
            refreshCurrentInvoiceAmount(productId);
        }
        return 1;
    }
    private void refreshCurrentInvoiceAmount(Long salesLedgerProductId) {
        // æŸ¥è¯¢è¯¥äº§å“æœ€æ–°ä¸€æ¡æ¥ç¥¨è®°å½•
        LambdaQueryWrapper<ProductRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductRecord::getSaleLedgerProjectId, salesLedgerProductId)
                .orderByDesc(ProductRecord::getCreatedAt)
                .last("limit 1");
        ProductRecord latestRecord = productRecordMapper.selectOne(wrapper);
        SalesLedgerProduct product =
                salesLedgerProductMapper.selectById(salesLedgerProductId);
        if (product == null) {
            return;
        }
        if (latestRecord == null) {
            //  æ²¡æœ‰ä»»ä½•来票记录
            product.setTicketsAmount(BigDecimal.ZERO);
        } else {
            //  æ°¸è¿œå–最新一条
            product.setTicketsAmount(latestRecord.getTicketsAmount());
        }
        salesLedgerProductMapper.updateById(product);
    }
    @Override
    public TicketRegistrationDto getRegistrationById(TicketRegistrationDto ticketRegistrationDto) {
        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(ticketRegistrationDto.getId());
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
@@ -3,6 +3,9 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectFile;
@@ -12,6 +15,7 @@
import com.ruoyi.quality.service.IQualityInspectParamService;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.quality.service.IQualityUnqualifiedService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -34,6 +38,8 @@
    @Resource
    private IQualityInspectFileService qualityInspectFileService;
    @Autowired
    private ProcurementRecordService procurementRecordService;
    /**
@@ -62,6 +68,8 @@
        //删除检验附件
        qualityInspectFileService.remove(Wrappers.<QualityInspectFile>lambdaQuery()
        .in(QualityInspectFile::getInspectId,ids));
        //删除入库记录
        procurementRecordService.remove(Wrappers.<ProcurementRecordStorage>lambdaQuery().in(ProcurementRecordStorage::getQualityInspectId,ids));
        //删除检验单
        return AjaxResult.success(qualityInspectService.removeBatchByIds(ids));
    }
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -138,6 +138,7 @@
     */
    private Integer inspectState;
    //采购台账产品id
    private Long purchaseLedgerId;
    /**
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -56,7 +56,7 @@
@AllArgsConstructor
@Service
@Transactional(rollbackFor = Exception.class)
public class QualityInspectServiceImpl extends ServiceImpl<QualityInspectMapper, QualityInspect>  implements IQualityInspectService {
public class QualityInspectServiceImpl extends ServiceImpl<QualityInspectMapper, QualityInspect> implements IQualityInspectService {
    private QualityInspectMapper qualityInspectMapper;
@@ -73,7 +73,7 @@
    @Override
    public int add(QualityInspectDto qualityInspectDto) {
        QualityInspect qualityInspect = new QualityInspect();
        BeanUtils.copyProperties(qualityInspectDto,qualityInspect);
        BeanUtils.copyProperties(qualityInspectDto, qualityInspect);
        qualityInspect.setInspectState(0);//默认未提交
        qualityInspectMapper.insert(qualityInspect);
        for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
@@ -88,7 +88,7 @@
        QualityInspect qualityInspect = qualityInspectMapper.selectById(id);
        List<QualityInspectParam> qualityInspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, id));
        QualityInspectDto qualityInspectDto = new QualityInspectDto();
        BeanUtils.copyProperties(qualityInspect,qualityInspectDto);
        BeanUtils.copyProperties(qualityInspect, qualityInspectDto);
        qualityInspectDto.setQualityInspectParams(qualityInspectParams);
        return qualityInspectDto;
    }
@@ -98,89 +98,94 @@
    public int submit(QualityInspect inspect) {
        QualityInspect qualityInspect = qualityInspectMapper.selectById(inspect.getId());
        /*判断不合格*/
        if (ObjectUtils.isNotNull(qualityInspect.getCheckResult()) && qualityInspect.getCheckResult().equals("不合格")){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (ObjectUtils.isNotNull(qualityInspect.getCheckResult()) && qualityInspect.getCheckResult().equals("不合格")) {
            QualityUnqualified qualityUnqualified = new QualityUnqualified();
            BeanUtils.copyProperties(qualityInspect,qualityUnqualified);
            BeanUtils.copyProperties(qualityInspect, qualityUnqualified);
            qualityUnqualified.setInspectState(0);//待处理
            List<QualityInspectParam> inspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, inspect.getId()));
            String text = inspectParams.stream().map(QualityInspectParam::getParameterItem).collect(Collectors.joining(","));
            qualityUnqualified.setDefectivePhenomena(text+"这些指标中存在不合格");//不合格现象
            qualityUnqualified.setDefectivePhenomena(text + "这些指标中存在不合格");//不合格现象
            qualityUnqualifiedMapper.insert(qualityUnqualified);
        }
        } else {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (qualityInspect.getInspectType() == 0) {
            if ("合格".equals(qualityInspect.getCheckResult())) {
                ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
                procurementRecordOutAdd.setType(1);
                procurementRecordOutAdd.setTypeName("采购入库");
                procurementRecordOutAdd.setNickName(loginUser.getNickName());
                procurementRecordOutAdd.setPurchaseLedgerId(Math.toIntExact(qualityInspect.getPurchaseLedgerId()));
                if (qualityInspect.getPurchaseLedgerId() == null) {
                    throw new BaseException("请选择采购单");
            if (qualityInspect.getInspectType() == 0) {
                if ("合格".equals(qualityInspect.getCheckResult())) {
                    ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
                    procurementRecordOutAdd.setType(1);
                    procurementRecordOutAdd.setTypeName("采购原材料检验合格入库");
                    procurementRecordOutAdd.setNickName(loginUser.getNickName());
                    procurementRecordOutAdd.setPurchaseLedgerId(Math.toIntExact(qualityInspect.getPurchaseLedgerId()));
                    if (qualityInspect.getPurchaseLedgerId() == null) {
                        throw new BaseException("请选择采购单");
                    }
                    SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(qualityInspect.getPurchaseLedgerId());
                    ArrayList<Details> detailss = new ArrayList<>();
                    Details details = new Details();
                    details.setId(Math.toIntExact(salesLedgerProduct.getId()));
                    details.setInboundQuantity(qualityInspect.getQuantity());
                    details.setWarnNum(salesLedgerProduct.getWarnNum());
                    details.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
                    details.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
                    details.setProductModelId(qualityInspect.getProductModelId());
                    detailss.add(details);
                    procurementRecordOutAdd.setDetails(detailss);
                    procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
                    procurementRecordService.add(procurementRecordOutAdd);
                }
                SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(qualityInspect.getProductId());
            } else if (qualityInspect.getInspectType() == 1) {
                //查询UnitPrice/TotalPrice
                ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
                procurementRecordOutAdd.setType(2);
                procurementRecordOutAdd.setTypeName("生产过程检验合格入库");
                procurementRecordOutAdd.setNickName(loginUser.getNickName());
                List<Details> details = new ArrayList<>();
                Details details1 = new Details();
                details1.setInboundQuantity(qualityInspect.getQuantity());
                details1.setProductModelId(qualityInspect.getProductModelId());
                procurementRecordOutAdd.setDetails(details);
                ArrayList<Details> detailss = new ArrayList<>();
                Details details = new Details();
                details.setId(Math.toIntExact(salesLedgerProduct.getId()));
                details.setInboundQuantity(qualityInspect.getQuantity());
                details.setWarnNum(salesLedgerProduct.getWarnNum());
                details.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
                details.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
                details.setProductModelId(qualityInspect.getProductModelId());
                detailss.add( details);
                procurementRecordOutAdd.setDetails(detailss);
                ProcurementRecordStorage.ProcurementRecordStorageBuilder procurementRecordBuilder = ProcurementRecordStorage.builder()
                        .salesLedgerProductId(0)
                        .inboundBatches("生产半成品入库")
                        .inboundNum(details1.getInboundQuantity())
                        .type(2)
                        .warnNum(new BigDecimal(0))
                        .unitPrice(new BigDecimal(0))
                        .totalPrice(new BigDecimal(0))
                        .createTime(LocalDateTime.now())
                        .createUser(loginUser.getUserId())
                        .updateTime(LocalDateTime.now())
                        .updateUser(loginUser.getUserId())
                        .createBy(procurementRecordOutAdd.getNickName())
                        .productModelId(details1.getProductModelId())
                        .qualityInspectId(qualityInspect.getId());
                procurementRecordService.save(procurementRecordBuilder.build());
            } else if (qualityInspect.getInspectType() == 2) {
                //查询UnitPrice/TotalPrice
                SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectSalesLedgerProductByMainId(qualityInspect.getProductMainId());
                ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
                procurementRecordOutAdd.setType(2);
                procurementRecordOutAdd.setTypeName("生产出厂检验合格入库");
                procurementRecordOutAdd.setNickName(loginUser.getNickName());
                List<Details> details = new ArrayList<>();
                Details details1 = new Details();
                details1.setInboundQuantity(qualityInspect.getQuantity());
                details1.setId(Math.toIntExact(salesLedgerProduct.getId()));
                details1.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
                details1.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
                details1.setProductModelId(salesLedgerProduct.getProductModelId());
                details.add(details1);
                procurementRecordOutAdd.setDetails(details);
                procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
                procurementRecordService.add(procurementRecordOutAdd);
            }
        }else if (qualityInspect.getInspectType() == 1) {
            //查询UnitPrice/TotalPrice
            ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
            procurementRecordOutAdd.setType(2);
            procurementRecordOutAdd.setTypeName("生产入库");
            procurementRecordOutAdd.setNickName(loginUser.getNickName());
            List<Details> details = new ArrayList<>();
            Details details1 = new Details();
            details1.setInboundQuantity(qualityInspect.getQuantity());
            details1.setProductModelId(qualityInspect.getProductModelId());
            procurementRecordOutAdd.setDetails(details);
            ProcurementRecordStorage.ProcurementRecordStorageBuilder procurementRecordBuilder = ProcurementRecordStorage.builder()
                    .salesLedgerProductId(0)
                    .inboundBatches( "生产半成品入库")
                    .inboundNum(details1.getInboundQuantity())
                    .type(2)
                    .warnNum(new BigDecimal(0))
                    .unitPrice(new BigDecimal(0))
                    .totalPrice(new BigDecimal(0))
                    .createTime(LocalDateTime.now())
                    .createUser(loginUser.getUserId())
                    .updateTime(LocalDateTime.now())
                    .updateUser(loginUser.getUserId())
                    .createBy(procurementRecordOutAdd.getNickName())
                    .productModelId(details1.getProductModelId());
            procurementRecordService.save(procurementRecordBuilder.build());
        }else if (qualityInspect.getInspectType() == 2) {
            //查询UnitPrice/TotalPrice
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectSalesLedgerProductByMainId(qualityInspect.getProductMainId());
            ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
            procurementRecordOutAdd.setType(2);
            procurementRecordOutAdd.setTypeName("生产入库");
            procurementRecordOutAdd.setNickName(loginUser.getNickName());
            List<Details> details = new ArrayList<>();
            Details details1 = new Details();
            details1.setInboundQuantity(qualityInspect.getQuantity());
            details1.setId(Math.toIntExact(salesLedgerProduct.getId()));
            details1.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
            details1.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
            details1.setProductModelId(salesLedgerProduct.getProductModelId());
            details.add(details1);
            procurementRecordOutAdd.setDetails(details);
            procurementRecordService.add(procurementRecordOutAdd);
        }
        qualityInspect.setInspectState(1);//已提交
        return qualityInspectMapper.updateById(qualityInspect);
    }
@@ -189,16 +194,16 @@
    @Override
    public void down(HttpServletResponse response, QualityInspect qualityInspect) {
        QualityInspect inspect = qualityInspectMapper.selectById(qualityInspect.getId());
        String inspectType="";
        switch (inspect.getInspectType()){
        String inspectType = "";
        switch (inspect.getInspectType()) {
            case 0:
                inspectType="原材料检验";
                inspectType = "原材料检验";
                break;
            case 1:
                inspectType="过程检验";
                inspectType = "过程检验";
                break;
            case 2:
                inspectType="出厂检验";
                inspectType = "出厂检验";
                break;
        }
        List<QualityInspectParam> paramList = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, inspect.getId()));
@@ -240,31 +245,31 @@
    @Override
    public int updateQualityInspect(QualityInspectDto qualityInspectDto) {
        if (ObjectUtils.isNotNull(qualityInspectDto.getQualityInspectParams())) {
            qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId,qualityInspectDto.getId()));
            qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, qualityInspectDto.getId()));
            for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
                qualityInspectParam.setInspectId(qualityInspectDto.getId());
            }
            qualityInspectParamService.saveBatch(qualityInspectDto.getQualityInspectParams());
        }
        QualityInspect qualityInspect = new QualityInspect();
        BeanUtils.copyProperties(qualityInspectDto,qualityInspect);
        BeanUtils.copyProperties(qualityInspectDto, qualityInspect);
        return qualityInspectMapper.updateById(qualityInspect);
    }
    @Override
    public IPage<QualityInspect> qualityInspectListPage(Page page, QualityInspect qualityInspect) {
        return qualityInspectMapper.qualityInspectListPage(page,qualityInspect);
        return qualityInspectMapper.qualityInspectListPage(page, qualityInspect);
    }
    @Override
    public void qualityInspectExport(HttpServletResponse response, QualityInspect qualityInspect) {
        List<QualityInspect> qualityInspects =qualityInspectMapper.qualityInspectExport(qualityInspect);
        List<QualityInspect> qualityInspects = qualityInspectMapper.qualityInspectExport(qualityInspect);
        ExcelUtil<QualityInspect> util = new ExcelUtil<QualityInspect>(QualityInspect.class);
        switch (qualityInspect.getInspectType()){
        switch (qualityInspect.getInspectType()) {
            case 0:
                util.exportExcel(response, qualityInspects, "原材料检验导出");
                break;
            case  1:
            case 1:
                util.exportExcel(response, qualityInspects, "过程检验导出");
                break;
            case 2:
src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
@@ -65,7 +65,7 @@
            BigDecimal stockQuantity = stockUtils.getStockQuantity(item.getProductModelId()).get("stockQuantity");
            if(stockQuantity != null) {
//                ProcurementPageDtoCopy procurementDtoCopy = result.getRecords().get(0);
                if (item.getQuantity().compareTo(stockQuantity) >= 0 && item.getApproveStatus() == 0) {
                if (item.getQuantity().compareTo(stockQuantity) <= 0 && item.getApproveStatus() == 0) {
                    item.setApproveStatus(1);
                    salesLedgerProductService.addOrUpdateSalesLedgerProduct(item);
                }
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
@@ -3,6 +3,7 @@
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.google.common.math.LongMath;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.controller.BaseController;
@@ -88,20 +89,22 @@
        //  å®¡æ‰¹é€šè¿‡
        if (req.getApproveStatus() == 3) {
            // æŸ¥è¯¢é‡‡è´­å…¥åº“记录
            LambdaQueryWrapper<ProcurementRecordStorage> lambdaQueryWrapper = new LambdaQueryWrapper<ProcurementRecordStorage>()
                    .eq(ProcurementRecordStorage::getSalesLedgerProductId, req.getSalesLedgerProductId());
            ProcurementRecordStorage procurementRecordStorage = procurementRecordStorageService.getOne(lambdaQueryWrapper);
            if (procurementRecordStorage == null) {
                // ä¿è¯å‰é¢çš„修改全部回滚
                throw new ServiceException("采购记录不存在,审批回滚");
            }
//            // æŸ¥è¯¢é‡‡è´­å…¥åº“记录
//            LambdaQueryWrapper<ProcurementRecordStorage> lambdaQueryWrapper = new LambdaQueryWrapper<ProcurementRecordStorage>()
//                    .eq(ProcurementRecordStorage::getSalesLedgerProductId, req.getSalesLedgerProductId());
//            ProcurementRecordStorage procurementRecordStorage = procurementRecordStorageService.getOne(lambdaQueryWrapper);
//
//            if (procurementRecordStorage == null) {
//                // ä¿è¯å‰é¢çš„修改全部回滚
//                throw new ServiceException("采购记录不存在,审批回滚");
//            }
            //  ç”Ÿæˆå‡ºåº“记录
            ProcurementRecordOutAdd procurementRecordOutAdd = new ProcurementRecordOutAdd();
            procurementRecordOutAdd.setId(procurementRecordStorage.getId());
            procurementRecordOutAdd.setSalesLedgerProductId(salesLedgerProduct.getId());
//            procurementRecordOutAdd.setId(procurementRecordStorage.getId());
            procurementRecordOutAdd.setId(0);
            procurementRecordOutAdd.setProductModelId(salesLedgerProduct.getProductModelId());
            procurementRecordOutAdd.setSalesLedgerProductId((long) Math.toIntExact(salesLedgerProduct.getId()));
            procurementRecordOutAdd.setType(2);
            procurementRecordOutAdd.setUserId(Math.toIntExact(getUserId()));
            procurementRecordOutAdd.setQuantity(salesLedgerProduct.getQuantity().toPlainString());
src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
@@ -2,6 +2,8 @@
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.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -70,6 +72,13 @@
                invoiceAmountTotal = invoiceAmountTotal.add(currentInvoiceNum);
                InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct();
                BeanUtils.copyProperties(productDatum, invoiceRegistrationProduct);
                //更新已开票剩余未开票数
                invoiceRegistrationProductMapper.update(
                        null,
                        new LambdaUpdateWrapper<InvoiceRegistrationProduct>()
                                .eq(InvoiceRegistrationProduct::getSalesLedgerId, salesLedgerDto.getId())
                                .set(InvoiceRegistrationProduct::getNoInvoiceAmount, productDatum.getNoInvoiceAmount())
                );
                invoiceRegistrationProduct.setId(null);
                invoiceRegistrationProduct.setSalesLedgerId(salesLedgerDto.getId().intValue());
                invoiceRegistrationProduct.setInvoiceRegistrationId(invoiceRegistration.getId());
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -3,11 +3,14 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.sales.dto.InvoiceRegistrationProductDto;
import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
@@ -42,6 +45,7 @@
public class SalesLedgerProductServiceImpl extends ServiceImpl<SalesLedgerProductMapper, SalesLedgerProduct> implements ISalesLedgerProductService {
    private SalesLedgerProductMapper salesLedgerProductMapper;
    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    private SalesLedgerMapper salesLedgerMapper;
@@ -59,6 +63,10 @@
    private ProductProcessRouteMapper productProcessRouteMapper;
    private ProductWorkOrderMapper productWorkOrderMapper;
    private ProductionProductMainMapper productionProductMainMapper;
    private ProductionProductOutputMapper productionProductOutputMapper;
    private ProductionProductInputMapper productionProductInputMapper;
    private QualityInspectMapper qualityInspectMapper;
    @Override
    public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -87,10 +95,10 @@
                        if(ledgerProduct.getId().intValue() == registrationProductDto.getSalesLedgerProductId()){
                            invoiceNum =  invoiceNum.add(registrationProductDto.getInvoiceNum());
                            invoiceAmount = invoiceAmount.add(registrationProductDto.getInvoiceAmount());
                            noInvoiceNum = ledgerProduct.getQuantity().subtract(invoiceNum);
                            noInvoiceAmount = ledgerProduct.getTaxInclusiveTotalPrice().subtract(invoiceAmount);
                        }
                    }
                    noInvoiceNum = ledgerProduct.getQuantity().subtract(invoiceNum);
                    noInvoiceAmount = ledgerProduct.getTaxInclusiveTotalPrice().subtract(invoiceAmount);
                    ledgerProduct.setInvoiceNum(invoiceNum);
                    ledgerProduct.setInvoiceAmount(invoiceAmount);
                    ledgerProduct.setNoInvoiceNum(noInvoiceNum);
@@ -193,76 +201,18 @@
        if (salesLedgerProduct.getId() == null) {
            salesLedgerProduct.setRegisterDate(LocalDateTime.now());
            result = salesLedgerProductMapper.insert(salesLedgerProduct);
            ProductOrder productOrder = new ProductOrder();
            productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
            productOrder.setProductModelId(salesLedgerProduct.getId());
            productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
            productOrder.setQuantity(salesLedgerProduct.getQuantity());//需求数量
            productOrder.setCompleteQuantity(BigDecimal.ZERO);//完成数量
            productOrderMapper.insert(productOrder);
            ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
            if (processRoute != null) {
                //新增生产订单工艺路线主表
                ProductProcessRoute productProcessRoute = new ProductProcessRoute();
                productProcessRoute.setProductModelId(processRoute.getProductModelId());
                productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
                productProcessRoute.setProductOrderId(productOrder.getId());
                productProcessRoute.setBomId(processRoute.getBomId());
                productProcessRouteMapper.insert(productProcessRoute);
                //新增生产订单工艺路线子表
                List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
                // ç”Ÿæˆå½“前日期的前缀:年月日
                String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                for (ProcessRouteItem processRouteItem : processRouteItems) {
                    ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                    productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                    productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                    productProcessRouteItem.setProductOrderId(productOrder.getId());
                    productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
                    int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                    if (insert > 0) {
                        // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
                        QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                        queryWrapper.likeRight("work_order_no", datePrefix)
                                .orderByDesc("work_order_no")
                                .last("LIMIT 1");
                        ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                        int sequenceNumber = 1; // é»˜è®¤åºå·
                        if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                            String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                            if (lastNo.startsWith(datePrefix)) {
                                String seqStr = lastNo.substring(datePrefix.length());
                                try {
                                    sequenceNumber = Integer.parseInt(seqStr) + 1;
                                } catch (NumberFormatException e) {
                                    sequenceNumber = 1;
                                }
                            }
                        }
                        // ç”Ÿæˆå®Œæ•´çš„工单号
                        String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                        ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                        productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                        productWorkOrder.setProductOrderId(productOrder.getId());
                        productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
                        productWorkOrder.setWorkOrderNo(workOrderNoStr);
                        productWorkOrder.setStatus(1);
                        productWorkOrderMapper.insert(productWorkOrder);
                    }
                }
                productOrder.setRouteId(processRoute.getId());
                productOrderMapper.updateById(productOrder);
            }
            addProductionData(salesLedgerProduct);
        } else {
            //查询原本的产品型号id
            salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
            result = salesLedgerProductMapper.updateById(salesLedgerProduct);
            /*删除对应的生产数据并重新新增*/
            deleteProductionData(Arrays.asList(salesLedgerProduct.getId()));
            // åˆ é™¤ç”Ÿäº§æ ¸ç®—数据
            LambdaQueryWrapper<SalesLedgerProductionAccounting> reportWrapper = new LambdaQueryWrapper<>();
            reportWrapper.in(SalesLedgerProductionAccounting::getSalesLedgerId, salesLedgerId);
            salesLedgerProductionAccountingMapper.delete(reportWrapper);
            addProductionData(salesLedgerProduct);
        }
        // å¦‚果插入或更新成功,并且有 salesLedgerId,才继续更新主表金额
@@ -296,6 +246,165 @@
    }
    /**
     * æ–°å¢žç”Ÿäº§æ•°æ®
     */
    public void addProductionData(SalesLedgerProduct salesLedgerProduct) {
        ProductOrder productOrder = new ProductOrder();
        productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
        productOrder.setProductModelId(salesLedgerProduct.getId());
        productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
        productOrder.setQuantity(salesLedgerProduct.getQuantity());//需求数量
        productOrder.setCompleteQuantity(BigDecimal.ZERO);//完成数量
        productOrderMapper.insert(productOrder);
        List<ProcessRoute> processRoutes = processRouteMapper.selectList(new QueryWrapper<ProcessRoute>().lambda()
                .eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId())
                .orderByDesc(ProcessRoute::getCreateTime));
        if (processRoutes.size()>0){
            ProcessRoute processRoute = processRoutes.get(0);
            //新增生产订单工艺路线主表
            ProductProcessRoute productProcessRoute = new ProductProcessRoute();
            productProcessRoute.setProductModelId(processRoute.getProductModelId());
            productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
            productProcessRoute.setProductOrderId(productOrder.getId());
            productProcessRoute.setBomId(processRoute.getBomId());
            productProcessRouteMapper.insert(productProcessRoute);
            //新增生产订单工艺路线子表
            List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
            // ç”Ÿæˆå½“前日期的前缀:年月日
            String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            for (ProcessRouteItem processRouteItem : processRouteItems) {
                ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                productProcessRouteItem.setProductOrderId(productOrder.getId());
                productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
                productProcessRouteItem.setDragSort(processRouteItem.getDragSort());
                int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                if (insert > 0) {
                    // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
                    QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                    queryWrapper.likeRight("work_order_no", datePrefix)
                            .orderByDesc("work_order_no")
                            .last("LIMIT 1");
                    ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                    int sequenceNumber = 1; // é»˜è®¤åºå·
                    if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                        String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                        if (lastNo.startsWith(datePrefix)) {
                            String seqStr = lastNo.substring(datePrefix.length());
                            try {
                                sequenceNumber = Integer.parseInt(seqStr) + 1;
                            } catch (NumberFormatException e) {
                                sequenceNumber = 1;
                            }
                        }
                    }
                    // ç”Ÿæˆå®Œæ•´çš„工单号
                    String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                    ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                    productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                    productWorkOrder.setProductOrderId(productOrder.getId());
                    productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
                    productWorkOrder.setWorkOrderNo(workOrderNoStr);
                    productWorkOrder.setStatus(1);
                    productWorkOrderMapper.insert(productWorkOrder);
                }
            }
            productOrder.setRouteId(processRoute.getId());
            productOrderMapper.updateById(productOrder);
        }
    }
    /**
     * åˆ é™¤ç”Ÿäº§æ•°æ®
     */
    public void deleteProductionData(List<Long> productIds) {
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
                        .in(ProductOrder::getProductModelId, productIds)
        );
        if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) {
            List<Long> orderIds = productOrders.stream()
                    .map(ProductOrder::getId)
                    .collect(Collectors.toList());
            // æ‰¹é‡æŸ¥è¯¢processRouteItems
            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                    new LambdaQueryWrapper<ProductProcessRouteItem>()
                            .in(ProductProcessRouteItem::getProductOrderId, orderIds)
            );
            if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(allRouteItems)) {
                // èŽ·å–è¦åˆ é™¤çš„å·¥åºé¡¹ID
                List<Long> routeItemIds = allRouteItems.stream()
                        .map(ProductProcessRouteItem::getId)
                        .collect(Collectors.toList());
                // æŸ¥è¯¢å…³è”的工单ID
                List<ProductWorkOrder> workOrders = productWorkOrderMapper.selectList(
                        new LambdaQueryWrapper<ProductWorkOrder>()
                                .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds)
                );
                if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(workOrders)) {
                    List<Long> workOrderIds = workOrders.stream()
                            .map(ProductWorkOrder::getId)
                            .collect(Collectors.toList());
                    // æŸ¥è¯¢å…³è”的生产主表ID
                    List<ProductionProductMain> productMains = productionProductMainMapper.selectList(
                            new LambdaQueryWrapper<ProductionProductMain>()
                                    .in(ProductionProductMain::getWorkOrderId, workOrderIds)
                    );
                    List<Long> productMainIds = productMains.stream()
                            .map(ProductionProductMain::getId)
                            .collect(Collectors.toList());
                    // åˆ é™¤äº§å‡ºè¡¨ã€æŠ•入表数据
                    if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(productMainIds)) {
                        productionProductOutputMapper.deleteByProductMainIds(productMainIds);
                        productionProductInputMapper.deleteByProductMainIds(productMainIds);
                        List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
                                new LambdaQueryWrapper<QualityInspect>()
                                        .in(QualityInspect::getProductMainId, productMainIds)
                        );
                        qualityInspects.forEach(qualityInspect -> {
                            //inspectState=1 å·²æäº¤ ä¸èƒ½åˆ é™¤
                            if (qualityInspect.getInspectState() == 1) {
                                throw new RuntimeException("已提交的检验单不能删除");
                            }
                        });
                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
                    }
                    // åˆ é™¤ç”Ÿäº§ä¸»è¡¨æ•°æ®
                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
                    // åˆ é™¤å·¥å•数据
                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
                }
            }
            // æ‰¹é‡åˆ é™¤processRouteItem
            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
                    .in(ProductProcessRouteItem::getProductOrderId, orderIds));
            // æ‰¹é‡åˆ é™¤productProcessRoute
            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
                    .in(ProductProcessRoute::getProductOrderId, orderIds));
            // æ‰¹é‡åˆ é™¤productOrder
            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
                    .in(ProductOrder::getProductModelId, productIds));
        }
    }
    /**
     * é€šç”¨æ–¹æ³•:根据主表ID和子表列表,更新主表的合同金额
     */
    public <T, S> void updateMainContractAmount(
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -32,6 +32,7 @@
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.*;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -77,6 +78,7 @@
    private final CustomerMapper customerMapper;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private final SalesLedgerProductServiceImpl salesLedgerProductServiceImpl;
    private final CommonFileMapper commonFileMapper;
@@ -91,7 +93,7 @@
    private final SalesLedgerWorkMapper salesLedgerWorkMapper;
    private final SalesLedgerProductionAccountingMapper  salesLedgerProductionAccountingMapper;
    private final SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    private final InvoiceRegistrationMapper invoiceRegistrationMapper;
@@ -178,7 +180,7 @@
    @Override
    public List<Map<String, Object>> getSalesNo() {
        LambdaQueryWrapper<SalesLedger> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(SalesLedger::getId, SalesLedger::getSalesContractNo, SalesLedger::getProjectName);
        queryWrapper.select(SalesLedger::getId, SalesLedger::getSalesContractNo);
        // èŽ·å–åŽŸå§‹æŸ¥è¯¢ç»“æžœ
        List<Map<String, Object>> result = salesLedgerMapper.selectMaps(queryWrapper);
@@ -217,8 +219,8 @@
        // æŸ¥è¯¢åŽŸå§‹æ•°æ®
        LambdaQueryWrapper<SalesLedger> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(SalesLedger::getCustomerId,
                        SalesLedger::getCustomerName,
                        SalesLedger::getContractAmount)
                SalesLedger::getCustomerName,
                SalesLedger::getContractAmount)
                .orderByDesc(SalesLedger::getContractAmount);
        List<SalesLedger> records = salesLedgerMapper.selectList(queryWrapper);
@@ -226,7 +228,7 @@
        Map<Long, GroupedCustomer> groupedMap = new LinkedHashMap<>(); // ä½¿ç”¨LinkedHashMap保持排序
        for (SalesLedger record : records) {
            groupedMap.computeIfAbsent(record.getCustomerId(),
                            k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName()))
                    k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName()))
                    .addAmount(record.getContractAmount());
        }
@@ -393,86 +395,8 @@
        List<Long> productIds = products.stream()
                .map(SalesLedgerProduct::getId)
                .collect(Collectors.toList());
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
                        .in(ProductOrder::getProductModelId, productIds)
        );
        if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) {
            List<Long> orderIds = productOrders.stream()
                    .map(ProductOrder::getId)
                    .collect(Collectors.toList());
            // æ‰¹é‡æŸ¥è¯¢processRouteItems
            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                    new LambdaQueryWrapper<ProductProcessRouteItem>()
                            .in(ProductProcessRouteItem::getProductOrderId, orderIds)
            );
            if (!CollectionUtils.isEmpty(allRouteItems)) {
                // èŽ·å–è¦åˆ é™¤çš„å·¥åºé¡¹ID
                List<Long> routeItemIds = allRouteItems.stream()
                        .map(ProductProcessRouteItem::getId)
                        .collect(Collectors.toList());
                // æŸ¥è¯¢å…³è”的工单ID
                List<ProductWorkOrder> workOrders = productWorkOrderMapper.selectList(
                        new LambdaQueryWrapper<ProductWorkOrder>()
                                .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds)
                );
                if (!CollectionUtils.isEmpty(workOrders)) {
                    List<Long> workOrderIds = workOrders.stream()
                            .map(ProductWorkOrder::getId)
                            .collect(Collectors.toList());
                    // æŸ¥è¯¢å…³è”的生产主表ID
                    List<ProductionProductMain> productMains = productionProductMainMapper.selectList(
                            new LambdaQueryWrapper<ProductionProductMain>()
                                    .in(ProductionProductMain::getWorkOrderId, workOrderIds)
                    );
                    List<Long> productMainIds = productMains.stream()
                            .map(ProductionProductMain::getId)
                            .collect(Collectors.toList());
                    // åˆ é™¤äº§å‡ºè¡¨ã€æŠ•入表数据
                    if (!CollectionUtils.isEmpty(productMainIds)) {
                        productionProductOutputMapper.deleteByProductMainIds(productMainIds);
                        productionProductInputMapper.deleteByProductMainIds(productMainIds);
                        List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
                                new LambdaQueryWrapper<QualityInspect>()
                                        .in(QualityInspect::getProductMainId, productMainIds)
                        );
                        qualityInspects.forEach(qualityInspect -> {
                            //inspectState=1 å·²æäº¤ ä¸èƒ½åˆ é™¤
                            if(qualityInspect.getInspectState() == 1){
                                throw new RuntimeException("已提交的检验单不能删除");
                            }
                        });
                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
                    }
                    // åˆ é™¤ç”Ÿäº§ä¸»è¡¨æ•°æ®
                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
                    // åˆ é™¤å·¥å•数据
                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
                }
            }
            // æ‰¹é‡åˆ é™¤processRouteItem
            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
                    .in(ProductProcessRouteItem::getProductOrderId, orderIds));
            // æ‰¹é‡åˆ é™¤productProcessRoute
            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
                    .in(ProductProcessRoute::getProductOrderId, orderIds));
            // æ‰¹é‡åˆ é™¤productOrder
            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
                    .in(ProductOrder::getProductModelId, productIds));
        }
        //删除生产数据
        salesLedgerProductServiceImpl.deleteProductionData(productIds);
        // æ‰¹é‡åˆ é™¤äº§å“å­è¡¨
        if (!productIds.isEmpty()) {
@@ -483,11 +407,11 @@
        wrapper.in(InvoiceRegistrationProduct::getSalesLedgerId, idList);
        List<InvoiceRegistrationProduct> invoiceRegistrationProducts = invoiceRegistrationProductMapper.selectList(wrapper);
        List<Integer> invoiceLedgerIds = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(invoiceRegistrationProducts)){
        if (CollectionUtils.isNotEmpty(invoiceRegistrationProducts)) {
            LambdaQueryWrapper<InvoiceLedger> wrapperOne = new LambdaQueryWrapper<>();
            wrapperOne.in(InvoiceLedger::getInvoiceRegistrationProductId, invoiceRegistrationProducts.stream().map(InvoiceRegistrationProduct::getId).collect(Collectors.toList()));
            List<InvoiceLedger> invoiceLedgers = invoiceLedgerMapper.selectList(wrapperOne);
            if(CollectionUtils.isNotEmpty(invoiceLedgers)){
            if (CollectionUtils.isNotEmpty(invoiceLedgers)) {
                invoiceLedgerIds = invoiceLedgers.stream().map(InvoiceLedger::getId).collect(Collectors.toList());
            }
            invoiceLedgerMapper.delete(wrapperOne);
@@ -497,7 +421,7 @@
        wrapperTwo.in(InvoiceRegistration::getSalesLedgerId, idList);
        invoiceRegistrationMapper.delete(wrapperTwo);
        if(CollectionUtils.isNotEmpty(invoiceLedgerIds)){
        if (CollectionUtils.isNotEmpty(invoiceLedgerIds)) {
            LambdaQueryWrapper<ReceiptPayment> wrapperTree = new LambdaQueryWrapper<>();
            wrapperTree.in(ReceiptPayment::getInvoiceLedgerId, invoiceLedgerIds);
            receiptPaymentMapper.delete(wrapperTree);
@@ -512,7 +436,7 @@
        LambdaQueryWrapper<SalesLedgerWork> workOrderWrapper = new LambdaQueryWrapper<>();
        workOrderWrapper.in(SalesLedgerWork::getSalesLedgerId, idList);
        salesLedgerWorkMapper.delete(workOrderWrapper);
        // åˆ é™¤ç”Ÿäº§æŠ¥å·¥æ•°æ®
        // åˆ é™¤ç”Ÿäº§æ ¸ç®—数据
        LambdaQueryWrapper<SalesLedgerProductionAccounting> reportWrapper = new LambdaQueryWrapper<>();
        reportWrapper.in(SalesLedgerProductionAccounting::getSalesLedgerId, idList);
        salesLedgerProductionAccountingMapper.delete(reportWrapper);
@@ -693,73 +617,8 @@
                salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
                salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                salesLedgerProductMapper.insert(salesLedgerProduct);
                ProductOrder productOrder = new ProductOrder();
                productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
                productOrder.setProductModelId(salesLedgerProduct.getId());
                productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
                productOrder.setQuantity(salesLedgerProduct.getQuantity());//需求数量
                productOrder.setCompleteQuantity(BigDecimal.ZERO);//完成数量
                productOrderMapper.insert(productOrder);
                ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
                if (processRoute != null) {
                    //新增生产订单工艺路线主表
                    ProductProcessRoute productProcessRoute = new ProductProcessRoute();
                    productProcessRoute.setProductModelId(processRoute.getProductModelId());
                    productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
                    productProcessRoute.setProductOrderId(productOrder.getId());
                    productProcessRoute.setBomId(processRoute.getBomId());
                    productProcessRouteMapper.insert(productProcessRoute);
                    //新增生产订单工艺路线子表
                    List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
                    // ç”Ÿæˆå½“前日期的前缀:年月日
                    String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                    for (ProcessRouteItem processRouteItem : processRouteItems) {
                        ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                        productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                        productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                        productProcessRouteItem.setProductOrderId(productOrder.getId());
                        productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
                        productProcessRouteItem.setDragSort(processRouteItem.getDragSort());
                        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                        if (insert > 0) {
                            // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
                            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                            queryWrapper.likeRight("work_order_no", datePrefix)
                                    .orderByDesc("work_order_no")
                                    .last("LIMIT 1");
                            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                            int sequenceNumber = 1; // é»˜è®¤åºå·
                            if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                                String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                                if (lastNo.startsWith(datePrefix)) {
                                    String seqStr = lastNo.substring(datePrefix.length());
                                    try {
                                        sequenceNumber = Integer.parseInt(seqStr) + 1;
                                    } catch (NumberFormatException e) {
                                        sequenceNumber = 1;
                                    }
                                }
                            }
                            // ç”Ÿæˆå®Œæ•´çš„工单号
                            String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                            ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                            if (Objects.equals(productProcessRouteItem.getProductModelId(), salesLedgerProduct.getProductModelId())) {
                                productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
                            }
                            productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                            productWorkOrder.setProductOrderId(productOrder.getId());
                            productWorkOrder.setWorkOrderNo(workOrderNoStr);
                            productWorkOrder.setStatus(1);
                            productWorkOrderMapper.insert(productWorkOrder);
                        }
                    }
                    productOrder.setRouteId(processRoute.getId());
                    productOrderMapper.updateById(productOrder);
                }
                // æ·»åŠ ç”Ÿäº§æ•°æ®
                salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
            }
        }
    }
src/main/resources/application-dev.yml
@@ -63,9 +63,9 @@
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://localhost:3306/product-inventory-management-hckx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://114.132.189.42:9099/product-inventory-management-sqd?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
@@ -136,14 +136,14 @@
  redis:
    # åœ°å€
    host: 127.0.0.1
    #    host: 172.17.0.1
#    host: 172.17.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç 
    #    password: root2022!
    password:
#    password: root2022!
    password: 123456
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
src/main/resources/mapper/basic/ProductModelMapper.xml
@@ -33,5 +33,68 @@
            LIMIT 1
    </select>
    <select id="listPageProductionStock" resultType="com.ruoyi.basic.pojo.ProductModel">
        SELECT
        pm.id,
        pm.product_id,
        pm.model,
        pm.unit,
        p.product_name,
        GREATEST(s.last_in_time, o.last_out_time) AS create_time,
        COALESCE(s.inboundNum, 0) AS inboundNum,
        COALESCE(o.outboundNum, 0) AS outboundNum,
        COALESCE(s.inboundNum, 0) - COALESCE(o.outboundNum, 0) AS stockQuantity
        FROM product_model pm
        LEFT JOIN product p ON pm.product_id = p.id
        -- å…¥åº“汇总
        LEFT JOIN (
        SELECT
        product_model_id,
        SUM(inbound_num) AS inboundNum,
        MAX(create_time) AS last_in_time
        FROM procurement_record_storage
        <where>
            <if test="req.timeStr != null and req.timeStr != ''">
                AND create_time &gt;= #{req.timeStr}
                AND create_time &lt; DATE_ADD(#{req.timeStr}, INTERVAL 1 DAY)
            </if>
        </where>
        GROUP BY product_model_id
        ) s ON s.product_model_id = pm.id
        -- å‡ºåº“汇总
        LEFT JOIN (
        SELECT
        product_model_id,
        SUM(inbound_num) AS outboundNum,
        MAX(create_time) AS last_out_time
        FROM procurement_record_out
        <where>
            <if test="req.timeStr != null and req.timeStr != ''">
                AND create_time &gt;= #{req.timeStr}
                AND create_time &lt; DATE_ADD(#{req.timeStr}, INTERVAL 1 DAY)
            </if>
        </where>
        GROUP BY product_model_id
        ) o ON o.product_model_id = pm.id
        <where>
            <if test="req.timeStr != null and req.timeStr != ''">
                AND (s.product_model_id IS NOT NULL OR o.product_model_id IS NOT NULL)
            </if>
            <if test="req.productCategory != null and req.productCategory != ''">
                AND EXISTS (
                SELECT 1
                FROM sales_ledger_product slp
                WHERE slp.product_id = p.id
                AND slp.product_category LIKE CONCAT('%', #{req.productCategory}, '%')
                )
            </if>
        </where>
        ORDER BY pm.id DESC
    </select>
</mapper>
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -371,6 +371,7 @@
    <select id="listPageByProductProduction" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDto">
        select
        t1.*,
        t1.inbound_num as inboundNum0,
        t2.model as specification_model  ,
        t2.unit,
        t3.product_name as product_category
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -43,6 +43,9 @@
            <if test="c.specificationModel != null and c.specificationModel != ''">
                and slp.specification_model like concat('%',#{c.specificationModel},'%')
            </if>
            <if test="c.startTime != null and c.endTime != null">
                and po.create_time between #{c.startTime} and #{c.endTime}
            </if>
        </where>
    </select>
    <select id="productMainByOrderId" resultType="com.ruoyi.production.dto.ProductOrderDto">
src/main/resources/mapper/production/ProductStructureMapper.xml
@@ -25,7 +25,7 @@
        where ps.bom_id = #{bomId}
        order by ps.id
    </select>
    <select id="listByproductModelId" resultType="com.ruoyi.production.dto.ProductStructureDto">
    <select id="listBybomAndProcess" resultType="com.ruoyi.production.dto.ProductStructureDto">
        select ps.*,
               p.product_name,
               pp.name as  process_name,
@@ -33,11 +33,11 @@
               pm.model
        from
            product_structure ps
                left join product_bom pb on ps.bom_id = pb.id
                left join product_model pm on ps.product_model_id = pm.id
                left join product p on pm.product_id = p.id
                left join product_process pp on ps.process_id = pp.id
        where pb.product_model_id = #{productModelId}
        where ps.bom_id = #{bomId}
        and ps.process_id=#{processId}
        order by ps.id
    </select>
    <select id="listBybomAndProcess" resultType="com.ruoyi.production.dto.ProductStructureDto">
src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -38,33 +38,9 @@
            <if test="c.workOrderNo != null and c.workOrderNo != ''">
                pwo.work_order_no like concat('%',#{c.workOrderNo},'%')
            </if>
            <if test="c.planStartTime != null and c.planEndTime != null">
                and DATE(pwo.create_time) between #{c.planStartTime} and #{c.planEndTime}
            </if>
        </where>
    </select>
    <select id="selectProductWorkOrderDtoList" resultType="com.ruoyi.production.dto.ProductWorkOrderDto">
        select *
        from product_work_order pwo
        left join product_order po on po.id = pwo.product_order_id
    </select>
    <update id="updatePlanQuantity" parameterType="java.util.Map">
        UPDATE product_work_order
        SET
            report_work = #{reportWork},
            plan_quantity = plan_quantity - #{deductQuantity}
        WHERE id = #{workOrderId}
    </update>
    <update id="rollbackPlanQuantity" parameterType="java.lang.Long">
        UPDATE product_work_order pwo
        INNER JOIN production_product_main ppm
        ON pwo.id = ppm.work_order_id
        AND ppm.id = #{productMainId}
        INNER JOIN production_product_output ppo
        ON ppo.product_main_id = ppm.id
        SET
        pwo.plan_quantity = pwo.plan_quantity + ppo.quantity,
        pwo.report_work = 0,
        pwo.quantity = 0
        WHERE pwo.id = ppm.work_order_id
    </update>
</mapper>
src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -13,11 +13,14 @@
    <select id="listPageProductionProductInputDto" resultType="com.ruoyi.production.dto.ProductionProductInputDto">
        select ppi.*,
        pm.model as model,
        ppm.product_no as productNo
        ppm.product_no as productNo,
        p.product_name,
        pm.unit
        from
        production_product_input ppi
        left join production_product_main ppm on ppm.id = ppi.product_main_id
        left join product_model pm on pm.id = ppi.product_model_id
        left join product p on p.id = pm.product_id
        <where>
            <if test="c.productMainId != null and c.productMainId > 0">
                and ppm.id = #{c.productMainId}
src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -16,10 +16,20 @@
        select ppm.*,
               pwo.work_order_no as workOrderNo,
               pwo.status as workOrderStatus,
               u.nick_name as nickName
               u.nick_name as nickName,
               p.product_name as productName,
               pm.model as productModelName,
               ppo.quantity,
               pm.unit,
               sl.sales_contract_no salesContractNo
        from
            production_product_main ppm
                left join product_work_order pwo on pwo.id = ppm.work_order_id
                left join product_order po on po.id = pwo.product_order_id
                left join production_product_output ppo on ppm.id = ppo.product_main_id
                left join product_model pm on pm.id = ppo.product_model_id
                left join product p on p.id = pm.product_id
                left join sales_ledger sl on sl.id = po.sales_ledger_id
                left join sys_user u on u.user_id = ppm.user_id
        <where>
            <if test="c.nickName != null and c.nickName != ''">
@@ -36,6 +46,7 @@
            </if>
        </where>
        order by ppm.id
    </select>
    <delete id="deleteByWorkOrderIds" parameterType="java.util.List">