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; } }