huminmin
3 天以前 bb302afba7c479d313d513370ea7dd6ac4da3c21
src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -13,10 +13,22 @@
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import java.time.LocalDateTime;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.dto.StockUninventoryDto;
import com.ruoyi.stock.execl.StockInRecordExportData;
import com.ruoyi.production.mapper.ProductionOrderPickMapper;
import com.ruoyi.production.pojo.ProductionOrderPick;
import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
import com.ruoyi.procurementrecord.mapper.ReturnSaleProductMapper;
import com.ruoyi.procurementrecord.pojo.ReturnManagement;
import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.stock.mapper.StockInRecordMapper;
import com.ruoyi.stock.mapper.StockInventoryMapper;
import com.ruoyi.stock.mapper.StockUninventoryMapper;
@@ -30,6 +42,7 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.List;
@Service
@@ -39,6 +52,11 @@
    private StockInRecordMapper stockInRecordMapper;
    private StockInventoryMapper stockInventoryMapper;
    private StockUninventoryMapper stockUninventoryMapper;
    private ProductionOrderPickMapper productionOrderPickMapper;
    private ReturnSaleProductMapper returnSaleProductMapper;
    private ReturnManagementMapper returnManagementMapper;
    private ShippingInfoMapper shippingInfoMapper;
    private SalesLedgerMapper salesLedgerMapper;
    @Override
    public IPage<StockInRecordDto> listPage(Page page, StockInRecordDto stockInRecordDto) {
@@ -49,8 +67,13 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int add(StockInRecordDto stockInRecordDto) {
        String no = OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK","inbound_batches");
        LocalDateTime createTime = stockInRecordDto.getCreateTime();
        if (createTime == null) {
            createTime = LocalDateTime.now();
        }
        String no = OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK","inbound_batches", createTime);
        stockInRecordDto.setInboundBatches(no);
        stockInRecordDto.setCreateTime(createTime);
        StockInRecord stockInRecord = new StockInRecord();
        BeanUtils.copyProperties(stockInRecordDto, stockInRecord);
        return stockInRecordMapper.insert(stockInRecord);
@@ -152,6 +175,32 @@
        return stockUninventoryMapper.selectOne(eq);
    }
    /**
     * 回滚生产退料入库的领料记录退料数量
     * @param stockInRecord 入库记录
     */
    private void rollbackFeedReturnQty(StockInRecord stockInRecord) {
        ProductionOrderPick productionOrderPick = productionOrderPickMapper.selectById(stockInRecord.getRecordId());
        if (productionOrderPick != null) {
            BigDecimal returnQty = productionOrderPick.getReturnQty();
            if (returnQty == null) {
                returnQty = BigDecimal.ZERO;
            }
            BigDecimal newReturnQty = returnQty.subtract(stockInRecord.getStockInNum());
            if (newReturnQty.compareTo(BigDecimal.ZERO) < 0) {
                newReturnQty = BigDecimal.ZERO;
            }
            productionOrderPick.setReturnQty(newReturnQty);
            // 重新计算实际用量
            BigDecimal actualQty = productionOrderPick.getQuantity().add(
                productionOrderPick.getFeedingQty() != null ? productionOrderPick.getFeedingQty() : BigDecimal.ZERO)
                .subtract(newReturnQty);
            productionOrderPick.setActualQty(actualQty);
            productionOrderPick.setReturned(newReturnQty.compareTo(BigDecimal.ZERO) > 0);
            productionOrderPickMapper.updateById(productionOrderPick);
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchDeletePending(List<Long> ids) {
@@ -162,6 +211,11 @@
            }
            if (stockInRecord.getApprovalStatus() != null && !ReviewStatusEnum.PENDING_REVIEW.getCode().equals(stockInRecord.getApprovalStatus())) {
                throw new BaseException("只有待审批状态的记录才能删除,入库批次:" + stockInRecord.getInboundBatches());
            }
            // 如果是生产退料入库,删除时需要回滚领料记录的退料数量
            if (StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode().equals(stockInRecord.getRecordType())) {
                rollbackFeedReturnQty(stockInRecord);
            }
        }
        return stockInRecordMapper.deleteBatchIds(ids);
@@ -186,6 +240,13 @@
            }
            stockInRecord.setApprovalStatus(approvalStatus);
            stockInRecordMapper.updateById(stockInRecord);
            // 审批驳回时,如果是生产退料入库,需要回滚领料记录的退料数量
            if (ReviewStatusEnum.REJECTED.getCode().equals(approvalStatus) &&
                StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode().equals(stockInRecord.getRecordType())) {
                rollbackFeedReturnQty(stockInRecord);
            }
            // 审批通过时,库存增加
            if (ReviewStatusEnum.APPROVED.getCode().equals(approvalStatus)) {
                if ("0".equals(stockInRecord.getType())) {
@@ -197,13 +258,18 @@
                    stockInventoryDto.setQualitity(stockInRecord.getStockInNum());
                    stockInventoryDto.setRemark(stockInRecord.getRemark());
                    if (stockInventory == null) {
                        stockInventoryMapper.insert(new StockInventory() {{
                            setProductModelId(stockInRecord.getProductModelId());
                            setQualitity(stockInRecord.getStockInNum());
                            setBatchNo(stockInRecord.getBatchNo());
                            setRemark(stockInRecord.getRemark());
                            setVersion(1);
                        }});
                        try {
                            stockInventoryMapper.insert(new StockInventory() {{
                                setProductModelId(stockInRecord.getProductModelId());
                                setQualitity(stockInRecord.getStockInNum());
                                setBatchNo(stockInRecord.getBatchNo());
                                setRemark(stockInRecord.getRemark());
                                setWarnNum(stockInRecord.getWarnNum());
                                setVersion(1);
                            }});
                        } catch (org.springframework.dao.DuplicateKeyException e) {
                            stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
                        }
                    } else {
                        stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
                    }
@@ -216,19 +282,114 @@
                    stockUninventoryDto.setQualitity(stockInRecord.getStockInNum());
                    stockUninventoryDto.setRemark(stockInRecord.getRemark());
                    if (stockUninventory == null) {
                        stockUninventoryMapper.insert(new StockUninventory() {{
                            setProductModelId(stockInRecord.getProductModelId());
                            setQualitity(stockInRecord.getStockInNum());
                            setBatchNo(stockInRecord.getBatchNo());
                            setRemark(stockInRecord.getRemark());
                            setVersion(1);
                        }});
                        try {
                            stockUninventoryMapper.insert(new StockUninventory() {{
                                setProductModelId(stockInRecord.getProductModelId());
                                setQualitity(stockInRecord.getStockInNum());
                                setBatchNo(stockInRecord.getBatchNo());
                                setRemark(stockInRecord.getRemark());
                                setVersion(1);
                            }});
                        } catch (org.springframework.dao.DuplicateKeyException e) {
                            stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
                        }
                    } else {
                        stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
                    }
                }
                // 销售退货入库:扣减销售台账实际合同金额(退货生效)
                handleSalesReturnRefund(stockInRecord);
            }
        }
        return ids.size();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchReAudit(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BaseException("请选择至少一条数据");
        }
        for (Long id : ids) {
            StockInRecord stockInRecord = stockInRecordMapper.selectById(id);
            if (stockInRecord == null) {
                throw new BaseException("入库记录不存在,无法重新审核!!!");
            }
            // 只有驳回状态才能重新审核
            if (!ReviewStatusEnum.REJECTED.getCode().equals(stockInRecord.getApprovalStatus())) {
                throw new BaseException("只有驳回状态的记录才能重新审核,入库批次:" + stockInRecord.getInboundBatches());
            }
            // 如果是生产退料入库,恢复退料数量(因为驳回时已扣减)
            if (StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode().equals(stockInRecord.getRecordType())) {
                ProductionOrderPick productionOrderPick = productionOrderPickMapper.selectById(stockInRecord.getRecordId());
                if (productionOrderPick != null) {
                    BigDecimal returnQty = productionOrderPick.getReturnQty();
                    if (returnQty == null) {
                        returnQty = BigDecimal.ZERO;
                    }
                    // 重新审核时恢复退料数量
                    BigDecimal newReturnQty = returnQty.add(stockInRecord.getStockInNum());
                    productionOrderPick.setReturnQty(newReturnQty);
                    // 重新计算实际用量
                    BigDecimal actualQty = productionOrderPick.getQuantity().add(
                        productionOrderPick.getFeedingQty() != null ? productionOrderPick.getFeedingQty() : BigDecimal.ZERO)
                        .subtract(newReturnQty);
                    productionOrderPick.setActualQty(actualQty);
                    productionOrderPick.setReturned(newReturnQty.compareTo(BigDecimal.ZERO) > 0);
                    productionOrderPickMapper.updateById(productionOrderPick);
                }
            }
            // 将状态改为待审核
            stockInRecord.setApprovalStatus(ReviewStatusEnum.PENDING_REVIEW.getCode());
            stockInRecordMapper.updateById(stockInRecord);
        }
        return ids.size();
    }
    /**
     * 销售退货入库审批通过时,扣减对应销售台账的实际合同金额。
     * 关联链:stock_in_record.record_id = return_sale_product.id
     *        → return_management.shipping_id = shipping_info.id
     *        → shipping_info.sales_ledger_id = sales_ledger.id
     * 只处理 record_type 为 14(合格)或 15(不合格)的销售退货入库。
     */
    private void handleSalesReturnRefund(StockInRecord stockInRecord) {
        String recordType = stockInRecord.getRecordType();
        if (!StockInQualifiedRecordTypeEnum.RETURN_HE_IN.getCode().equals(recordType)
                && !StockInQualifiedRecordTypeEnum.RETURN_UNSTOCK_IN.getCode().equals(recordType)) {
            return;
        }
        if (stockInRecord.getRecordId() == null) {
            return;
        }
        ReturnSaleProduct rsp = returnSaleProductMapper.selectById(stockInRecord.getRecordId());
        if (rsp == null || rsp.getReturnManagementId() == null) {
            return;
        }
        ReturnManagement rm = returnManagementMapper.selectById(rsp.getReturnManagementId());
        if (rm == null || rm.getShippingId() == null) {
            return;
        }
        ShippingInfo shippingInfo = shippingInfoMapper.selectById(rm.getShippingId());
        if (shippingInfo == null || shippingInfo.getSalesLedgerId() == null) {
            return;
        }
        SalesLedger salesLedger = salesLedgerMapper.selectById(shippingInfo.getSalesLedgerId());
        if (salesLedger == null || salesLedger.getContractAmount() == null) {
            return;
        }
        BigDecimal refund = rsp.getAmount() != null ? rsp.getAmount() : BigDecimal.ZERO;
        if (refund.compareTo(BigDecimal.ZERO) == 0) {
            return;
        }
        BigDecimal baseAmount = salesLedger.getNetContractAmount() != null
                ? salesLedger.getNetContractAmount()
                : salesLedger.getContractAmount();
        salesLedger.setNetContractAmount(baseAmount.subtract(refund));
        salesLedgerMapper.updateById(salesLedger);
    }
}