src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -3,8 +3,6 @@
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.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.procurementrecord.utils.StockUtils;
@@ -14,7 +12,6 @@
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.sales.dto.SalesLedgerProductDto;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
@@ -38,9 +35,13 @@
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
@@ -135,11 +136,13 @@
            shippingInfoService.delete(shippingInfos.stream().map(ShippingInfo::getId).collect(Collectors.toList()));
        }
        // 可能属于多个主表
        Set<Long> mainIds = deletedProducts.stream()
                .map(SalesLedgerProduct::getSalesLedgerId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 可能属于多个主表,按 type 分组(销售/采购产品子表共用且主表 id 可能相同)
        Map<Integer, Set<Long>> mainIdsByType = new HashMap<>();
        deletedProducts.stream()
                .filter(product -> product.getSalesLedgerId() != null)
                .forEach(product -> mainIdsByType
                        .computeIfAbsent(product.getType() == null ? 1 : product.getType(), key -> new HashSet<>())
                        .add(product.getSalesLedgerId()));
        // 2. 执行删除操作
        int result = salesLedgerProductMapper.deleteBatchIds(Arrays.asList(ids));
@@ -147,38 +150,39 @@
        deleteProductionData(Arrays.asList(ids));
        // 3. 对每个主表ID进行金额更新
        for (Long salesLedgerId : mainIds) {
            LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId);
            List<SalesLedgerProduct> remainingProducts = salesLedgerProductMapper.selectList(wrapper);
        mainIdsByType.forEach((type, mainIds) -> {
            for (Long salesLedgerId : mainIds) {
                LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId)
                        .eq(SalesLedgerProduct::getType, type);
                List<SalesLedgerProduct> remainingProducts = salesLedgerProductMapper.selectList(wrapper);
            // 调用通用方法更新主表金额
            updateMainContractAmount(
                    salesLedgerId,
                    remainingProducts,
                    SalesLedgerProduct::getTaxInclusiveTotalPrice,
                    salesLedgerMapper,
                    SalesLedger.class
            );
        }
                // 调用通用方法更新主表金额
                if (type == 1) {
                    updateMainContractAmount(
                            salesLedgerId,
                            remainingProducts,
                            SalesLedgerProduct::getTaxInclusiveTotalPrice,
                            salesLedgerMapper,
                            SalesLedger.class
                    );
                } else {
                    updateMainContractAmount(
                            salesLedgerId,
                            remainingProducts,
                            SalesLedgerProduct::getTaxInclusiveTotalPrice,
                            purchaseLedgerMapper,
                            PurchaseLedger.class
                    );
                }
            }
        });
        return result;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrUpdateSalesLedgerProduct(SalesLedgerProduct salesLedgerProduct) {
        // 待回款,付款
        if(salesLedgerProduct.getType().equals(1)){
            salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(salesLedgerProduct.getInvoiceTotal()));
            //未开票数量+金额
            salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
            salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
        }else{
            salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(salesLedgerProduct.getTicketsTotal()));
            // 未来票数量+金额
            salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
            salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
        }
        int result;
        Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
@@ -188,7 +192,6 @@
            addProductionData(salesLedgerProduct);
        } else {
            //查询原本的产品型号id
            salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
            result = salesLedgerProductMapper.updateById(salesLedgerProduct);
            /*删除对应的生产数据并重新新增*/
            deleteProductionData(Arrays.asList(salesLedgerProduct.getId()));
@@ -238,7 +241,8 @@
        ProductionPlan productionPlan = new ProductionPlan();
        productionPlan.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
        productionPlan.setSalesLedgerProductId(salesLedgerProduct.getId());
        productionPlan.setMpsNo(generateNextPlanNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
        productionPlan.setMpsNo(generateNextPlanNo(com.ruoyi.common.utils.DateUtils.toLocalDate(salesLedger.getEntryDate())
                .format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
        productionPlan.setProductModelId(salesLedgerProduct.getProductModelId());
        productionPlan.setQtyRequired(salesLedgerProduct.getQuantity());
        productionPlan.setSource("销售");
@@ -268,34 +272,6 @@
        }
        List<Long> ids = productionPlans.stream().map(ProductionPlan::getId).collect(Collectors.toList());
        productionPlanMapper.deleteByIds(ids);
    }
    @Override
    public IPage<SalesLedgerProductDto> listPage(Page page, SalesLedgerProductDto salesLedgerProduct) {
        IPage<SalesLedgerProductDto> salesLedgerProductDtoIPage = salesLedgerProductMapper.listPage(page, salesLedgerProduct);
        salesLedgerProductDtoIPage.getRecords().forEach(item -> {
            // 判断状态
            if(item.getTaxInclusiveTotalPrice().compareTo(item.getInvoiceTotal()) == 0){
                item.setStatusName("已完成付款");
            }else{
                item.setStatusName("未完成付款");
            }
        });
        return salesLedgerProductDtoIPage;
    }
    @Override
    public IPage<SalesLedgerProductDto> listPagePurchaseLedger(Page page, SalesLedgerProductDto salesLedgerProduct) {
        IPage<SalesLedgerProductDto> salesLedgerProductDtoIPage = salesLedgerProductMapper.listPagePurchaseLedger(page, salesLedgerProduct);
        salesLedgerProductDtoIPage.getRecords().forEach(item -> {
            // 判断状态
            if(item.getTaxInclusiveTotalPrice().compareTo(item.getTicketsTotal()) == 0){
                item.setStatusName("已完成付款");
            }else{
                item.setStatusName("未完成付款");
            }
        });
        return salesLedgerProductDtoIPage;
    }
    /**
@@ -363,7 +339,7 @@
            BigDecimal remain = stockInventory.getQualitity()
                    .subtract(stockInventory.getLockedQuantity())
                    .subtract(required)
                    .divide(BigDecimal.ONE, 2, RoundingMode.CEILING);
                    .divide(BigDecimal.ONE, 6, RoundingMode.CEILING);
            if (remain.compareTo(BigDecimal.ZERO) < 0) {
                count++;
                stringBuffer.append(structure.getProductName())