src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -5,17 +5,15 @@
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.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.impl.SalesLedgerProductionAccountingServiceImpl;
import com.ruoyi.production.service.impl.ProductOrderServiceImpl;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
@@ -26,7 +24,6 @@
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShippingInfo;
@@ -94,7 +91,7 @@
    @Autowired
    private StockInventoryMapper stockInventoryMapper;
    @Autowired
    private SalesLedgerProductionAccountingServiceImpl salesLedgerProductionAccountingServiceImpl;
    private ProductOrderServiceImpl productOrderServiceImpl;
    @Override
    public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -174,10 +171,9 @@
        }
        // 可能属于多个主表
        Set<Long> mainIds = deletedProducts.stream()
                .map(SalesLedgerProduct::getSalesLedgerId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Map<Long, Integer> mainIdTypeMap = deletedProducts.stream()
                .filter(p -> p.getSalesLedgerId() != null)
                .collect(Collectors.toMap(SalesLedgerProduct::getSalesLedgerId, SalesLedgerProduct::getType, (existing, replacement) -> existing));
        // 2. 执行删除操作
        int result = salesLedgerProductMapper.deleteBatchIds(Arrays.asList(ids));
@@ -185,19 +181,44 @@
        deleteProductionData(Arrays.asList(ids));
        // 3. 对每个主表ID进行金额更新
        for (Long salesLedgerId : mainIds) {
        for (Map.Entry<Long, Integer> entry : mainIdTypeMap.entrySet()) {
            Long salesLedgerId = entry.getKey();
            Integer type = entry.getValue();
            LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId);
            wrapper.eq(SalesLedgerProduct::getType, type);
            List<SalesLedgerProduct> remainingProducts = salesLedgerProductMapper.selectList(wrapper);
            // 调用通用方法更新主表金额
            updateMainContractAmount(
                    salesLedgerId,
                    remainingProducts,
                    SalesLedgerProduct::getTaxInclusiveTotalPrice,
                    salesLedgerMapper,
                    SalesLedger.class
            );
            if (type == 1) {
                SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerId);
                if (salesLedger != null) {
                    Function<SalesLedgerProduct, BigDecimal> amountGetter = Integer.valueOf(2).equals(salesLedger.getSalesType()) ?
                            p -> p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO
                            : p -> p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                    updateMainContractAmount(
                            salesLedgerId,
                            remainingProducts,
                            amountGetter,
                            salesLedgerMapper,
                            SalesLedger.class
                    );
                }
            } else {
                PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(salesLedgerId);
                if (purchaseLedger != null) {
                    Function<SalesLedgerProduct, BigDecimal> amountGetter = Integer.valueOf(2).equals(purchaseLedger.getPurchaseType()) ?
                            p -> p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO
                            : p -> p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
                    updateMainContractAmount(
                            salesLedgerId,
                            remainingProducts,
                            amountGetter,
                            purchaseLedgerMapper,
                            PurchaseLedger.class
                    );
                }
            }
        }
        return result;
    }
@@ -205,21 +226,86 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrUpdateSalesLedgerProduct(SalesLedgerProduct salesLedgerProduct) {
        if (salesLedgerProduct.getId() != null) {
            SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProduct.getId());
            if (dbProduct != null) {
                if (salesLedgerProduct.getSalesLedgerId() == null) {
                    salesLedgerProduct.setSalesLedgerId(dbProduct.getSalesLedgerId());
                }
                if (salesLedgerProduct.getType() == null) {
                    salesLedgerProduct.setType(dbProduct.getType());
                }
                if (salesLedgerProduct.getInvoiceTotal() == null) {
                    salesLedgerProduct.setInvoiceTotal(dbProduct.getInvoiceTotal());
                }
                if (salesLedgerProduct.getTicketsTotal() == null) {
                    salesLedgerProduct.setTicketsTotal(dbProduct.getTicketsTotal());
                }
                if (salesLedgerProduct.getQuantity() == null) {
                    salesLedgerProduct.setQuantity(dbProduct.getQuantity());
                }
                if (salesLedgerProduct.getTotalPrice() == null) {
                    salesLedgerProduct.setTotalPrice(dbProduct.getTotalPrice());
                }
                if (salesLedgerProduct.getTaxInclusiveTotalPrice() == null) {
                    salesLedgerProduct.setTaxInclusiveTotalPrice(dbProduct.getTaxInclusiveTotalPrice());
                }
                if (salesLedgerProduct.getTaxExclusiveTotalPrice() == null) {
                    salesLedgerProduct.setTaxExclusiveTotalPrice(dbProduct.getTaxExclusiveTotalPrice());
                }
                if (salesLedgerProduct.getTaxRate() == null) {
                    salesLedgerProduct.setTaxRate(dbProduct.getTaxRate());
                }
                if (salesLedgerProduct.getUnitPrice() == null) {
                    salesLedgerProduct.setUnitPrice(dbProduct.getUnitPrice());
                }
                if (salesLedgerProduct.getFreight() == null) {
                    salesLedgerProduct.setFreight(dbProduct.getFreight());
                }
                if (salesLedgerProduct.getPriceWithFreight() == null) {
                    salesLedgerProduct.setPriceWithFreight(dbProduct.getPriceWithFreight());
                }
            }
        }
        Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
        SalesLedger salesLedger = null;
        PurchaseLedger purchaseLedger = null;
        boolean isPrivate = false;
        if (salesLedgerProduct.getType() != null && salesLedgerProduct.getType().equals(1)) {
            salesLedger = salesLedgerMapper.selectById(salesLedgerId);
            if (salesLedger != null && Integer.valueOf(2).equals(salesLedger.getSalesType())) {
                isPrivate = true;
            }
        } else {
            purchaseLedger = purchaseLedgerMapper.selectById(salesLedgerId);
            if (purchaseLedger != null && Integer.valueOf(2).equals(purchaseLedger.getPurchaseType())) {
                isPrivate = true;
            }
        }
        BigDecimal totalPrice = isPrivate ?
                (salesLedgerProduct.getTotalPrice() != null ? salesLedgerProduct.getTotalPrice() : BigDecimal.ZERO) :
                (salesLedgerProduct.getTaxInclusiveTotalPrice() != null ? salesLedgerProduct.getTaxInclusiveTotalPrice() : BigDecimal.ZERO);
        BigDecimal invoiceTotal = salesLedgerProduct.getInvoiceTotal() != null ? salesLedgerProduct.getInvoiceTotal() : BigDecimal.ZERO;
        BigDecimal ticketsTotal = salesLedgerProduct.getTicketsTotal() != null ? salesLedgerProduct.getTicketsTotal() : BigDecimal.ZERO;
        // 待回款,付款
        if(salesLedgerProduct.getType().equals(1)){
            salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(salesLedgerProduct.getInvoiceTotal()));
            salesLedgerProduct.setPendingInvoiceTotal(totalPrice.subtract(invoiceTotal));
            //未开票数量+金额
            salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
            salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
            salesLedgerProduct.setNoInvoiceAmount(totalPrice);
        }else{
            salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(salesLedgerProduct.getTicketsTotal()));
            salesLedgerProduct.setPendingTicketsTotal(totalPrice.subtract(ticketsTotal));
            // 未来票数量+金额
            salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
            salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
            salesLedgerProduct.setFutureTicketsAmount(totalPrice);
        }
        int result;
        Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
        if (salesLedgerProduct.getId() == null) {
            salesLedgerProduct.setRegisterDate(LocalDateTime.now());
            result = salesLedgerProductMapper.insert(salesLedgerProduct);
@@ -242,12 +328,17 @@
            wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId)
                    .eq(SalesLedgerProduct::getType, salesLedgerProduct.getType());
            List<SalesLedgerProduct> productList = salesLedgerProductMapper.selectList(wrapper);
            Function<SalesLedgerProduct, BigDecimal> amountGetter = isPrivate ?
                    p -> p.getTotalPrice() != null ? p.getTotalPrice() : BigDecimal.ZERO
                    : p -> p.getTaxInclusiveTotalPrice() != null ? p.getTaxInclusiveTotalPrice() : BigDecimal.ZERO;
            if (salesLedgerProduct.getType() == 1) {
                // 调用通用方法更新主表金额
                updateMainContractAmount(
                        salesLedgerId,
                        productList,
                        SalesLedgerProduct::getTaxInclusiveTotalPrice,
                        amountGetter,
                        salesLedgerMapper,
                        SalesLedger.class
                );
@@ -256,7 +347,7 @@
                updateMainContractAmount(
                        salesLedgerId,
                        productList,
                        SalesLedgerProduct::getTaxInclusiveTotalPrice,
                        amountGetter,
                        purchaseLedgerMapper,
                        PurchaseLedger.class
                );
@@ -273,7 +364,8 @@
        productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
        productOrder.setProductModelId(salesLedgerProduct.getProductModelId());
        productOrder.setSaleLedgerProductId(salesLedgerProduct.getId());
        productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
        String string = productOrderServiceImpl.generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        productOrder.setNpsNo(string);
        productOrder.setQuantity(salesLedgerProduct.getQuantity());//需求数量
        productOrder.setCompleteQuantity(BigDecimal.ZERO);//完成数量
        productOrderMapper.insert(productOrder);
@@ -293,7 +385,7 @@
            //新增生产订单工艺路线子表
            List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
            // 生成当前日期的前缀:年月日
            String datePrefix = "GD" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            for (ProcessRouteItem processRouteItem : processRouteItems) {
                ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
@@ -304,13 +396,7 @@
                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);
                    ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
                    int sequenceNumber = 1; // 默认序号
                    if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                        String lastNo = lastWorkOrder.getWorkOrderNo().toString();
@@ -324,7 +410,7 @@
                        }
                    }
                    // 生成完整的工单号
                    String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                    String workOrderNoStr ="GD"+ String.format("%s%03d", datePrefix, sequenceNumber);
                    ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                    productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                    productWorkOrder.setProductOrderId(productOrder.getId());
@@ -345,6 +431,9 @@
     * 删除生产数据
     */
    public void deleteProductionData(List<Long> productIds) {
        if (productIds == null || productIds.isEmpty()){
            return;
        }
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
@@ -397,9 +486,9 @@
                        //删除出库记录
                        for (Long productMainId : productMainIds) {
                            //删除生产出库记录
                            stockUtils.deleteStockOutRecord(productMainId, StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
                            stockUtils.deleteStockOutRecord(productMainId, StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
                            //删除报废的入库记录
                            stockUtils.deleteStockInRecord(productMainId, StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
                            stockUtils.deleteStockInRecord(productMainId, StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
                        }
                        qualityInspects.forEach(qualityInspect -> {
                            //inspectState=1 已提交 不能删除