src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -4,9 +4,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.ruoyi.common.enums.ReviewStatusEnum; import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper; import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper; import com.ruoyi.sales.mapper.ShippingProductDetailMapper; import com.ruoyi.sales.pojo.ShippingProductDetail; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.dto.StockOutRecordDto; import com.ruoyi.stock.dto.StockUninventoryDto; import com.ruoyi.stock.pojo.StockInRecord; import com.ruoyi.stock.pojo.StockOutRecord; @@ -31,6 +35,7 @@ private final StockInventoryService stockInventoryService; private final StockInRecordService stockInRecordService; private final StockOutRecordService stockOutRecordService; private final ShippingProductDetailMapper shippingProductDetailMapper; /** * 不合格入库 @@ -154,15 +159,47 @@ } /** * 发货审批状态更改 * 只登记出库流水,不校验、不扣减库存。 * 用于未启用仓储模块、发货没有库存批号的场景。 * * @param productModelId * @param quantity * @param recordType * @param recordId * @param batchNo */ public void recordStockOutWithoutInventory(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String batchNo) { StockOutRecordDto stockOutRecordDto = new StockOutRecordDto(); stockOutRecordDto.setRecordId(recordId); stockOutRecordDto.setRecordType(String.valueOf(recordType)); stockOutRecordDto.setStockOutNum(quantity); stockOutRecordDto.setProductModelId(productModelId); stockOutRecordDto.setBatchNo(batchNo); stockOutRecordDto.setType("0"); stockOutRecordService.add(stockOutRecordDto); } /** * 发货审批状态更改。 * 没有库存批号的发货(未启用仓储模块)没有出库审核环节,审批通过即视为已出库, * 否则发货数量统计不到。 * * @param recordType * @param recordId */ public void shipmentStatus(String recordType, Long recordId) { Long inventoryBatchCount = shippingProductDetailMapper.selectCount(new LambdaQueryWrapper<ShippingProductDetail>() .eq(ShippingProductDetail::getShippingInfoId, recordId) .isNotNull(ShippingProductDetail::getStockInventoryId)); boolean withoutInventoryBatch = StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode().equals(recordType) && inventoryBatchCount == 0; Integer approvalStatus = withoutInventoryBatch ? ReviewStatusEnum.APPROVED.getCode() : ReviewStatusEnum.PENDING_REVIEW.getCode(); LambdaQueryWrapper<StockOutRecord> queryWrapper = new LambdaQueryWrapper<StockOutRecord>().eq(StockOutRecord::getRecordType, recordType) .eq(StockOutRecord::getRecordId, recordId); stockOutRecordService.list(queryWrapper).stream().forEach(stockOutRecord -> { stockOutRecord.setApprovalStatus(0); stockOutRecord.setApprovalStatus(approvalStatus); stockOutRecordService.updateById(stockOutRecord); }); } src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -85,7 +85,7 @@ throw new RuntimeException("发货信息不存在"); } for (ShippingProductDetail shippingProductDetail : shippingProductDetails) { stockUtils.substractStock(shippingProductDetail.getProductModelId(), shippingProductDetail.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(), shippingProductDetail.getBatchNo()); deductOrRecordStock(shippingProductDetail, req.getId()); } } byId.setExpressNumber(req.getExpressNumber()); @@ -143,16 +143,31 @@ @Override public boolean add(ShippingInfoDto req) { this.save(req); req.getBatchNoDetailList().forEach(item -> item.setShippingInfoId(req.getId())); shippingProductDetailMapper.insert(req.getBatchNoDetailList()); for (ShippingProductDetail shippingProductDetail : req.getBatchNoDetailList()) { stockUtils.substractStock(shippingProductDetail.getProductModelId(), shippingProductDetail.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(), shippingProductDetail.getBatchNo()); List<ShippingProductDetail> detailList = req.getBatchNoDetailList(); if (CollectionUtils.isNotEmpty(detailList)) { detailList.forEach(item -> item.setShippingInfoId(req.getId())); shippingProductDetailMapper.insert(detailList); for (ShippingProductDetail shippingProductDetail : detailList) { deductOrRecordStock(shippingProductDetail, req.getId()); } } // 保存文件 fileUtil.saveStorageAttachment(ApplicationTypeEnum.IMAGE, RecordTypeEnum.SHIPPING_INFO, req.getId(), req.getStorageBlobDTOs()); return true; } /** * 有库存批号的发货扣减库存;没有库存批号(未启用仓储模块)的发货只登记出库流水。 */ private void deductOrRecordStock(ShippingProductDetail detail, Long shippingInfoId) { String recordType = StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(); if (detail.getStockInventoryId() == null) { stockUtils.recordStockOutWithoutInventory(detail.getProductModelId(), detail.getQuantity(), recordType, shippingInfoId, detail.getBatchNo()); } else { stockUtils.substractStock(detail.getProductModelId(), detail.getQuantity(), recordType, shippingInfoId, detail.getBatchNo()); } } @Override public List<ShippingProductDetailDto> getDetail(Long id) { return shippingProductDetailMapper.getDetail(id); src/main/resources/mapper/sales/ShippingProductDetailMapper.xml
@@ -14,7 +14,7 @@ select si.batch_no, pm.model as specification_model, p.product_name, spd.quantity as delivery_quantity from shipping_product_detail spd left join stock_inventory si on si.id = spd.stock_inventory_id left join product_model pm on pm.id = si.product_model_id left join product_model pm on pm.id = IFNULL(si.product_model_id, spd.product_model_id) left join product p on p.id = pm.product_id where spd.shipping_info_id = #{id} </select> @@ -23,7 +23,7 @@ from shipping_product_detail spd left join shipping_info sp on sp.id = spd.shipping_info_id left join stock_inventory si on si.id = spd.stock_inventory_id left join product_model pm on pm.id = si.product_model_id left join product_model pm on pm.id = IFNULL(si.product_model_id, spd.product_model_id) left join product p on p.id = pm.product_id where sp.shipping_no = #{shippingNo} </select>