liyong
14 小时以前 74a29854bb8ff92d2ff2fcb55fa5028609ec6a33
采购删除导致审批报错+发货台账导入关联销售台账+生成出库记录
已修改8个文件
158 ■■■■ 文件已修改
src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/WeighingRecordController.java 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/WeighingRecord.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/IWeighingRecordService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/WeighingRecordServiceImpl.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
@@ -9,7 +9,8 @@
    PRODUCTION_REPORT_STOCK_OUT("3", "生产报工-出库"),
    SALE_STOCK_OUT("8", "销售-出库"),
    PURCHASE_RETURN_STOCK_OUT("9", "采购退货"),
    SALE_SHIP_STOCK_OUT("13", "销售-发货出库");
    SALE_SHIP_STOCK_OUT("13", "销售-发货出库"),
    WEIGHBRIDGE_OUT("33", "磅单出库");
    private final String code;
    private final String value;
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -232,7 +232,7 @@
        purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId());
        purchaseLedger.setRecorderName(sysUser.getNickName());
        purchaseLedger.setPhoneNumber(sysUser.getPhonenumber());
        purchaseLedger.setApprovalStatus(1);
        purchaseLedger.setApprovalStatus(3);
        List<SalesLedgerProduct> productList = Optional.ofNullable(purchaseLedgerDto.getProductData()).orElse(Collections.emptyList());
        // 3. 新增或更新主表
@@ -849,7 +849,9 @@
                if(salesLedger1 != null){
                    salesLedger.setSalesLedgerId(salesLedger1.getId());
                }
                // 采购审核
                // 设置为待审批状态
                salesLedger.setApprovalStatus(3);
                /* // 采购审核 - 已废弃,不再发起审批流程
                // 通过昵称获取用户ID
                String[] split = salesLedger.getApproveUserIds().split(",");
                List<Long> ids = new ArrayList<>();
@@ -862,7 +864,7 @@
                }
                // 将集合转为字符串,隔开
                String collect = ids.stream().map(Object::toString).collect(Collectors.joining(","));
                salesLedger.setApproveUserIds(collect);
                salesLedger.setApproveUserIds(collect); */
                purchaseLedgerMapper.insert(salesLedger);
                for (PurchaseLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) {
@@ -933,7 +935,7 @@
                    salesLedgerProductMapper.insert(salesLedgerProduct);
                }
                // 采购审核
                addApproveByPurchase(loginUser,salesLedger);
//                addApproveByPurchase(loginUser,salesLedger);
            }
            return AjaxResult.success("导入成功");
src/main/java/com/ruoyi/sales/controller/WeighingRecordController.java
@@ -16,11 +16,14 @@
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import static com.ruoyi.framework.datasource.DynamicDataSourceContextHolder.log;
/**
 * 过磅记录(磅单台账)Controller
@@ -74,11 +77,15 @@
            // 去重检查
            List<WeighingRecord> newRecordList = new ArrayList<>();
            int duplicateCount = 0;
            int matchedCount = 0;
            int unmatchedCount = 0;
            for (WeighingRecord record : weighingRecordList) {
                LambdaQueryWrapper<WeighingRecord> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(WeighingRecord::getSerialNo, record.getSerialNo());
                if (ObjectUtils.isEmpty(record.getSpecification())) {
                    record.setSpecification("/");
                }
                long count = weighingRecordService.count(wrapper);
                if (count == 0) {
                    newRecordList.add(record);
@@ -91,13 +98,33 @@
                return R.fail("所有数据都已存在,共" + duplicateCount + "条重复数据");
            }
            // 批量插入新数据
            weighingRecordService.saveBatch(newRecordList);
            // 批量插入新数据并执行出库操作
            for (WeighingRecord record : newRecordList) {
                // 先保存磅单记录,获取ID
                weighingRecordService.save(record);
            String message = String.format("导入成功:%d条,跳过重复:%d条", newRecordList.size(), duplicateCount);
                // 根据客户、产品名称、规格匹配销售台账并出库
                Long productId = weighingRecordService.matchAndOutStock(
                        record.getReceiveUnit(),      // 收货单位=客户
                        record.getGoodsName(),        // 货名=产品名称
                        record.getSpecification(),    // 规格型号
                        record.getNetWeight(),       // 净重=数量
                        record.getId()               // 磅单ID作为关联记录ID
                );
                if (productId != null) {
                    matchedCount++;
                } else {
                    unmatchedCount++;
                }
            }
            String message = String.format("导入成功:%d条,跳过重复:%d条,匹配出库:%d条,未匹配:%d条",
                    newRecordList.size(), duplicateCount, matchedCount, unmatchedCount);
            return R.ok(message);
        } catch (Exception e) {
            log.error("磅单导入失败:{}", e.getMessage());
            return R.fail("导入失败:" + e.getMessage());
        }
    }
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -12,7 +12,6 @@
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * 产品信息对象 sales_ledger_product
@@ -206,7 +205,7 @@
    @Excel(name = "发货日期", width = 30, dateFormat = "yyyy-MM-dd")
    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date shippingDate;
    private LocalDateTime shippingDate;
    @TableField(exist = false)
    @ApiModelProperty(value = "发货状态")
src/main/java/com/ruoyi/sales/pojo/WeighingRecord.java
@@ -87,4 +87,7 @@
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    private Long recordId;
}
src/main/java/com/ruoyi/sales/service/IWeighingRecordService.java
@@ -5,6 +5,10 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.sales.pojo.WeighingRecord;
import java.math.BigDecimal;
public interface IWeighingRecordService extends IService<WeighingRecord> {
    IPage<WeighingRecord> listPage(Page<WeighingRecord> page, WeighingRecord weighingRecord);
    Long matchAndOutStock(String receiveUnit, String goodsName, String specification, BigDecimal netWeight, Long id);
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -27,7 +27,9 @@
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.pojo.WeighingRecord;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.IWeighingRecordService;
import com.ruoyi.stock.mapper.StockInventoryMapper;
import com.ruoyi.stock.pojo.StockInventory;
import lombok.AllArgsConstructor;
@@ -88,13 +90,14 @@
    private StockUtils stockUtils;
    @Autowired
    private ProductStructureMapper productStructureMapper;
    @Autowired
    private StockInventoryMapper stockInventoryMapper;
    @Autowired
    private ProductOrderServiceImpl productOrderServiceImpl;
    @Autowired
    private IWeighingRecordService iWeighingRecordService;
    @Override
    public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -110,17 +113,20 @@
        if(!CollectionUtils.isEmpty(salesLedgerProducts)){
            salesLedgerProducts.forEach(item -> {
                // 发货信息
                ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
                        .eq(ShippingInfo::getSalesLedgerProductId, item.getId())
                        .orderByDesc(ShippingInfo::getCreateTime)
                        .last("limit 1"));
                if(shippingInfo != null){
                    item.setShippingDate(shippingInfo.getShippingDate());
                    item.setShippingCarNumber(shippingInfo.getShippingCarNumber());
                    item.setShippingStatus(shippingInfo.getStatus());
                    item.setExpressCompany(shippingInfo.getExpressCompany());
                    item.setExpressNumber(shippingInfo.getExpressNumber());
                List<WeighingRecord> list = iWeighingRecordService.list(new QueryWrapper<WeighingRecord>().lambda().eq(WeighingRecord::getRecordId, item.getId()).orderByDesc(WeighingRecord::getCreateTime));
                if (!list.isEmpty()) {
                    BigDecimal reduce = list.stream().map(WeighingRecord::getNetWeight).collect(Collectors.toList()).stream().reduce(BigDecimal.ZERO, BigDecimal::add);
                    item.setShippingDate(list.get(0).getSecondWeighTime());
                    item.setShippingCarNumber(list.get(0).getCarNo());
                    if (reduce.compareTo(BigDecimal.ZERO) == 0) {
                        item.setShippingStatus("未发货");
                    } else if (reduce.compareTo(item.getQuantity()) < 0) {
                        item.setShippingStatus("部分发货");
                    } else {
                        item.setShippingStatus("已发货");
                }
                }
                item.setShippingStatus("未发货");
            });
            // 开票
            InvoiceRegistrationProductDto invoiceRegistrationProductDto = new InvoiceRegistrationProductDto();
@@ -592,6 +598,7 @@
            throw new RuntimeException("动态更新主表金额失败", e);
        }
    }
    @Override
    public R judgmentInventory(SalesLedgerProduct salesLedgerProduct) {
        //获取产品最新的工艺路线
src/main/java/com/ruoyi/sales/service/impl/WeighingRecordServiceImpl.java
@@ -4,13 +4,22 @@
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.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.WeighingRecordMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.WeighingRecord;
import com.ruoyi.sales.service.IWeighingRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
@Service
@Slf4j
@@ -18,6 +27,9 @@
public class WeighingRecordServiceImpl extends ServiceImpl<WeighingRecordMapper, WeighingRecord> implements IWeighingRecordService {
    private final WeighingRecordMapper weighingRecordMapper;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private final SalesLedgerMapper salesLedgerMapper;
    private final StockUtils stockUtils;
    @Override
    public IPage<WeighingRecord> listPage(Page<WeighingRecord> page, WeighingRecord weighingRecord) {
@@ -43,4 +55,63 @@
                WeighingRecord::getShipUnit, weighingRecord.getShipUnit());
        return weighingRecordMapper.selectPage(page, queryWrapper);
    }
    /**
     * 根据客户、产品名称、规格型号匹配销售台账产品并出库
     * @param receiveUnit 收货单位(客户名称)
     * @param goodsName 货名(产品名称)
     * @param specification 规格
     * @param quantity 数量(净重)
     * @param recordId 磅单记录ID(作为关联记录ID)
     * @return 匹配到的销售台账产品ID,未匹配返回null
     */
    public Long matchAndOutStock(String receiveUnit, String goodsName, String specification, BigDecimal quantity, Long recordId) {
        // 1. 查询所有销售台账产品(只查询未发货的)
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SalesLedgerProduct::getType, 1);  // 销售类型
        List<SalesLedgerProduct> productList = salesLedgerProductMapper.selectList(queryWrapper);
        if (productList == null || productList.isEmpty()) {
            log.warn("未找到未发货的销售台账产品数据");
            return null;
        }
        // 2. 遍历匹配:客户名称 + 产品大类 + 规格型号
        for (SalesLedgerProduct product : productList) {
            // 获取对应的销售台账主表信息
            SalesLedger salesLedger = salesLedgerMapper.selectById(product.getSalesLedgerId());
            if (salesLedger == null) {
                continue;
            }
            // 匹配条件:收货单位=客户名称,货名=产品大类,规格=规格型号
            boolean customerMatch = receiveUnit != null && receiveUnit.equals(salesLedger.getCustomerName());
            boolean goodsMatch = goodsName != null && goodsName.equals(product.getProductCategory());
            boolean specMatch = specification != null && specification.equals(product.getSpecificationModel());
            if (customerMatch && goodsMatch && specMatch) {
                // 3. 匹配成功,执行出库
                try {
                    WeighingRecord weighingRecord = new WeighingRecord();
                    weighingRecord.setRecordId(product.getId());
                    weighingRecord.setId(recordId);
                    this.updateById(weighingRecord);
                    stockUtils.substractStock(
                            product.getProductModelId(),
                            quantity,
                            StockOutQualifiedRecordTypeEnum.WEIGHBRIDGE_OUT.getCode(),  // 磅单出库类型
                            recordId             // 磅单ID作为关联记录ID
                    );
                    log.info("磅单出库成功:客户={}, 产品={}, 规格={}, 数量={}, 磅单ID={}",
                            receiveUnit, goodsName, specification, quantity, recordId);
                    return product.getId();
                } catch (Exception e) {
                    log.error("磅单出库失败:{}", e.getMessage());
                    throw new RuntimeException("出库失败:" + e.getMessage());
                }
            }
        }
        log.warn("未匹配到销售台账产品:客户={}, 产品={}, 规格={}", receiveUnit, goodsName, specification);
        return null;
    }
}