gongchunyi
2 天以前 1511296b46ddc0ed8a285d2d19e5491ef3506488
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -3,9 +3,9 @@
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.common.exception.ServiceException;
import com.ruoyi.common.utils.AmountUtils;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.production.mapper.*;
@@ -14,9 +14,6 @@
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.sales.dto.InvoiceRegistrationProductDto;
import com.ruoyi.sales.dto.SalesLedgerProductDto;
import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
@@ -30,7 +27,7 @@
import com.ruoyi.technology.mapper.TechnologyBomStructureMapper;
import com.ruoyi.technology.mapper.TechnologyRoutingMapper;
import com.ruoyi.technology.pojo.TechnologyRouting;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -42,6 +39,7 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -55,41 +53,56 @@
 * @date 2025-05-08
 */
@Service
@RequiredArgsConstructor
public class SalesLedgerProductServiceImpl extends ServiceImpl<SalesLedgerProductMapper, SalesLedgerProduct> implements ISalesLedgerProductService {
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private final ProductionAccountMapper productionAccountMapper;
    private final SalesLedgerMapper salesLedgerMapper;
    private final PurchaseLedgerMapper purchaseLedgerMapper;
    private final ProductionPlanMapper productionPlanMapper;
    private final ProductionOperationTaskMapper productionOperationTaskMapper;
    private final ProductionOrderService productionOrderService;
    private final TechnologyRoutingMapper technologyRoutingMapper;
    private final TechnologyBomStructureMapper technologyBomStructureMapper;
    private final InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
    private final ProductionProductMainMapper productionProductMainMapper;
    private final ProductionProductOutputMapper productionProductOutputMapper;
    private final ProductionProductInputMapper productionProductInputMapper;
    private final QualityInspectMapper qualityInspectMapper;
    private final ShippingInfoMapper shippingInfoMapper;
    private final ShippingInfoServiceImpl shippingInfoService;
    private final StockUtils stockUtils;
    private final StockInventoryMapper stockInventoryMapper;
    @Autowired
    private SalesLedgerProductMapper salesLedgerProductMapper;
    @Autowired
    private ProductionAccountMapper productionAccountMapper;
    @Autowired
    private SalesLedgerMapper salesLedgerMapper;
    @Autowired
    private PurchaseLedgerMapper purchaseLedgerMapper;
    @Autowired
    private ProductionPlanMapper productionPlanMapper;
    @Autowired
    private ProductionOperationTaskMapper productionOperationTaskMapper;
    @Autowired
    private ProductionOrderService productionOrderService;
    @Autowired
    private TechnologyRoutingMapper technologyRoutingMapper;
    @Autowired
    private TechnologyBomStructureMapper technologyBomStructureMapper;
    @Autowired
    private ProductionProductMainMapper productionProductMainMapper;
    @Autowired
    private ProductionProductOutputMapper productionProductOutputMapper;
    @Autowired
    private ProductionProductInputMapper productionProductInputMapper;
    @Autowired
    private QualityInspectMapper qualityInspectMapper;
    @Autowired
    private ShippingInfoMapper shippingInfoMapper;
    @Autowired
    private ShippingInfoServiceImpl shippingInfoService;
    @Autowired
    private StockUtils stockUtils;
    @Autowired
    private StockInventoryMapper stockInventoryMapper;
    @Override
    public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
        return salesLedgerProductMapper.selectById(id);
        SalesLedgerProduct product = salesLedgerProductMapper.selectById(id);
        AmountUtils.normalizeSalesLedgerProduct(product);
        return product;
    }
    @Override
    public List<SalesLedgerProduct> selectSalesLedgerProductList(SalesLedgerProduct salesLedgerProduct) {
//        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerProduct.getSalesLedgerId())
//                .eq(SalesLedgerProduct::getType, salesLedgerProduct.getType());
        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectSalesLedgerProductList(salesLedgerProduct);
        if(!CollectionUtils.isEmpty(salesLedgerProducts)){
            salesLedgerProducts.forEach(item -> {
                AmountUtils.normalizeSalesLedgerProduct(item);
                // 发货信息
                ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
                        .eq(ShippingInfo::getSalesLedgerProductId, item.getId())
@@ -98,39 +111,10 @@
                if(shippingInfo != null){
                    item.setShippingDate(shippingInfo.getShippingDate());
                    item.setShippingCarNumber(shippingInfo.getShippingCarNumber());
                    item.setShippingStatus(shippingInfo.getStatus());
                    item.setExpressCompany(shippingInfo.getExpressCompany());
                    item.setExpressNumber(shippingInfo.getExpressNumber());
                }
            });
            // 开票
            InvoiceRegistrationProductDto invoiceRegistrationProductDto = new InvoiceRegistrationProductDto();
            invoiceRegistrationProductDto.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId().intValue());
            List<InvoiceRegistrationProductDto> invoiceRegistrationProductDtoList = invoiceRegistrationProductMapper.invoiceRegistrationProductList(invoiceRegistrationProductDto);
            // 统计开票登记产品的已开票数/已开票金额
            if (!CollectionUtils.isEmpty(invoiceRegistrationProductDtoList)) {
                for (SalesLedgerProduct ledgerProduct : salesLedgerProducts) {
                    BigDecimal invoiceNum = BigDecimal.ZERO;
                    BigDecimal invoiceAmount = BigDecimal.ZERO;
                    BigDecimal noInvoiceNum = BigDecimal.ZERO;
                    BigDecimal noInvoiceAmount = BigDecimal.ZERO;
                    for (InvoiceRegistrationProductDto registrationProductDto : invoiceRegistrationProductDtoList) {
                        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);
                    ledgerProduct.setInvoiceNum(invoiceNum);
                    ledgerProduct.setInvoiceAmount(invoiceAmount);
                    ledgerProduct.setNoInvoiceNum(noInvoiceNum);
                    ledgerProduct.setNoInvoiceAmount(noInvoiceAmount);
                }
            }
        }
        return salesLedgerProducts;
    }
@@ -186,18 +170,7 @@
    @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());
        }
        AmountUtils.normalizeSalesLedgerProduct(salesLedgerProduct);
        int result;
        Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
@@ -206,14 +179,9 @@
            result = salesLedgerProductMapper.insert(salesLedgerProduct);
            addProductionData(salesLedgerProduct);
        } else {
            //查询原本的产品型号id
            salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
            result = salesLedgerProductMapper.updateById(salesLedgerProduct);
            /*删除对应的生产数据并重新新增*/
            deleteProductionData(Arrays.asList(salesLedgerProduct.getId()));
            // 删除生产核算数据
            addProductionData(salesLedgerProduct);
            /*同步对应的生产数据:计划未下发时原地更新需求数量,保留生产计划号*/
            syncProductionData(salesLedgerProduct);
        }
        // 如果插入或更新成功,并且有 salesLedgerId,才继续更新主表金额
@@ -251,65 +219,82 @@
     */
    public void addProductionData(SalesLedgerProduct salesLedgerProduct) {
        //先判断该产品是否需要生产
        if (!salesLedgerProduct.getIsProduction()) {
        if (Boolean.TRUE.equals(salesLedgerProduct.getIsProduction())) {
            SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerProduct.getSalesLedgerId());
            ProductionPlan productionPlan = new ProductionPlan();
            productionPlan.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
            productionPlan.setSalesLedgerProductId(salesLedgerProduct.getId());
            productionPlan.setMpsNo(generateNextPlanNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
            productionPlan.setProductModelId(salesLedgerProduct.getProductModelId());
            productionPlan.setQtyRequired(salesLedgerProduct.getQuantity());
            productionPlan.setSource("销售");
            productionPlan.setStatus(0);
            productionPlan.setRequiredDate(salesLedger.getDeliveryDate());//需求日期=交货日期
            productionPlan.setPromisedDeliveryDate(salesLedger.getDeliveryDate());//承诺日期=交货日期
            productionPlanMapper.insert(productionPlan);
        }
    }
    /**
     * 同步生产数据
     * 需要生产:生产计划已下发时禁止修改;未下发时原地更新需求数量,保留生产计划号;
     * 改为走库存:删除未下发的生产计划。
     */
    public void syncProductionData(SalesLedgerProduct salesLedgerProduct) {
        if (salesLedgerProduct.getId() == null) {
            return;
        }
        ProductionPlan productionPlan = new ProductionPlan();
        productionPlan.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
        productionPlan.setSalesLedgerProductId(salesLedgerProduct.getId());
        productionPlan.setMpsNo(generateNextPlanNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
        productionPlan.setProductModelId(salesLedgerProduct.getProductModelId());
        productionPlan.setQtyRequired(salesLedgerProduct.getQuantity());
        productionPlan.setSource("销售");
        productionPlan.setStatus(0);
        productionPlanMapper.insert(productionPlan);
        List<ProductionPlan> productionPlans = listProductionData(salesLedgerProduct.getId());
        if (CollectionUtils.isEmpty(productionPlans)) {
            //原来不需要生产,现在改为需要生产,补建生产计划
            if (Boolean.TRUE.equals(salesLedgerProduct.getIsProduction())) {
                addProductionData(salesLedgerProduct);
            }
            return;
        }
        //改为走库存,删除未下发的生产计划
        if (!Boolean.TRUE.equals(salesLedgerProduct.getIsProduction())) {
            deleteProductionData(Collections.singletonList(salesLedgerProduct.getId()));
            return;
        }
        if (productionPlans.stream().anyMatch(plan -> plan.getStatus() != null && plan.getStatus() != 0)) {
            throw new ServiceException("生产计划已下发,不能修改该销售产品");
        }
        for (ProductionPlan productionPlan : productionPlans) {
            productionPlan.setQtyRequired(salesLedgerProduct.getQuantity());
            productionPlan.setProductModelId(salesLedgerProduct.getProductModelId());
            productionPlanMapper.updateById(productionPlan);
        }
    }
    /**
     * 删除生产计划
     */
    public void deleteProductionData(List<Long> productIds) {
        if (CollectionUtils.isEmpty(productIds)) {
            return;
        }
        List<ProductionPlan> productionPlans = productionPlanMapper.selectList(
                new LambdaQueryWrapper<ProductionPlan>()
                        .in(ProductionPlan::getSalesLedgerProductId, productIds.stream().map(Long::intValue).collect(Collectors.toList())));
        if (org.springframework.util.CollectionUtils.isEmpty(productionPlans)) {
                        .in(ProductionPlan::getSalesLedgerProductId, productIds));
        if (CollectionUtils.isEmpty(productionPlans)) {
            return;
        }
        //如果生产计划已下发则不能删除
        if (productionPlans.stream().anyMatch(productionPlan -> productionPlan.getStatus() != 0)) {
        if (productionPlans.stream().anyMatch(productionPlan -> productionPlan.getStatus() != null && productionPlan.getStatus() != 0)) {
            throw new RuntimeException("生产计划已下发,不能删除该销售产品");
        }
        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;
    /**
     * 查询销售产品对应的生产计划
     */
    private List<ProductionPlan> listProductionData(Long productId) {
        return productionPlanMapper.selectList(new LambdaQueryWrapper<ProductionPlan>()
                .eq(ProductionPlan::getSalesLedgerProductId, productId));
    }
    /**
@@ -339,7 +324,7 @@
            Field amountField = mainEntityClass.getDeclaredField("contractAmount");
            amountField.setAccessible(true);
            amountField.set(entity, totalAmount);
            amountField.set(entity, AmountUtils.scaleAmount(totalAmount));
            mainMapper.updateById(entity);
        } catch (Exception e) {