Commit f6d3290426fce784dded91579775a5af244208e0
1 parent
593e1fd5
✨ ERP:增加入库单号的自动生成
Showing
7 changed files
with
85 additions
and
6 deletions
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
| @@ -25,7 +25,7 @@ public interface ErrorCodeConstants { | @@ -25,7 +25,7 @@ public interface ErrorCodeConstants { | ||
| 25 | ErrorCode STOCK_IN_DELETE_FAIL_APPROVE = new ErrorCode(1_030_401_001, "其它入库单({})已审核,无法删除"); | 25 | ErrorCode STOCK_IN_DELETE_FAIL_APPROVE = new ErrorCode(1_030_401_001, "其它入库单({})已审核,无法删除"); |
| 26 | ErrorCode STOCK_IN_PROCESS_FAIL = new ErrorCode(1_030_401_002, "反审核失败,只有已审核的入库单才能反审核"); | 26 | ErrorCode STOCK_IN_PROCESS_FAIL = new ErrorCode(1_030_401_002, "反审核失败,只有已审核的入库单才能反审核"); |
| 27 | ErrorCode STOCK_IN_APPROVE_FAIL = new ErrorCode(1_030_401_003, "审核失败,只有未审核的入库单才能审核"); | 27 | ErrorCode STOCK_IN_APPROVE_FAIL = new ErrorCode(1_030_401_003, "审核失败,只有未审核的入库单才能审核"); |
| 28 | - | 28 | + ErrorCode STOCK_IN_NO_EXISTS = new ErrorCode(1_030_401_004, "生成入库单失败,请重新提交"); |
| 29 | 29 | ||
| 30 | // ========== ERP 产品 1-030-500-000 ========== | 30 | // ========== ERP 产品 1-030-500-000 ========== |
| 31 | ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在"); | 31 | ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在"); |
yudao-module-erp/yudao-module-erp-biz/pom.xml
| @@ -51,6 +51,11 @@ | @@ -51,6 +51,11 @@ | ||
| 51 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> | 51 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> |
| 52 | </dependency> | 52 | </dependency> |
| 53 | 53 | ||
| 54 | + <dependency> | ||
| 55 | + <groupId>cn.iocoder.boot</groupId> | ||
| 56 | + <artifactId>yudao-spring-boot-starter-redis</artifactId> | ||
| 57 | + </dependency> | ||
| 58 | + | ||
| 54 | <!-- 工具类相关 --> | 59 | <!-- 工具类相关 --> |
| 55 | <dependency> | 60 | <dependency> |
| 56 | <groupId>cn.iocoder.boot</groupId> | 61 | <groupId>cn.iocoder.boot</groupId> |
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInSaveReqVO.java
| @@ -17,10 +17,6 @@ public class ErpStockInSaveReqVO { | @@ -17,10 +17,6 @@ public class ErpStockInSaveReqVO { | ||
| 17 | @Schema(description = "入库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") | 17 | @Schema(description = "入库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") |
| 18 | private Long id; | 18 | private Long id; |
| 19 | 19 | ||
| 20 | - @Schema(description = "入库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "S123") | ||
| 21 | - @NotEmpty(message = "入库单号不能为空") | ||
| 22 | - private String no; | ||
| 23 | - | ||
| 24 | @Schema(description = "供应商编号", example = "3113") | 20 | @Schema(description = "供应商编号", example = "3113") |
| 25 | private Long supplierId; | 21 | private Long supplierId; |
| 26 | 22 |
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInMapper.java
| @@ -40,4 +40,8 @@ public interface ErpStockInMapper extends BaseMapperX<ErpStockInDO> { | @@ -40,4 +40,8 @@ public interface ErpStockInMapper extends BaseMapperX<ErpStockInDO> { | ||
| 40 | .eq(ErpStockInDO::getId, id).eq(ErpStockInDO::getStatus, status)); | 40 | .eq(ErpStockInDO::getId, id).eq(ErpStockInDO::getStatus, status)); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | + default ErpStockInDO selectByNo(String no) { | ||
| 44 | + return selectOne(ErpStockInDO::getNo, no); | ||
| 45 | + } | ||
| 46 | + | ||
| 43 | } | 47 | } |
| 44 | \ No newline at end of file | 48 | \ No newline at end of file |
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/RedisKeyConstants.java
0 → 100644
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.erp.dal.redis.no; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.date.DatePattern; | ||
| 4 | +import cn.hutool.core.date.DateUtil; | ||
| 5 | +import cn.iocoder.yudao.module.erp.dal.redis.RedisKeyConstants; | ||
| 6 | +import jakarta.annotation.Resource; | ||
| 7 | +import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 8 | +import org.springframework.stereotype.Repository; | ||
| 9 | + | ||
| 10 | +import java.time.Duration; | ||
| 11 | +import java.time.LocalDateTime; | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * 订单序号的 Redis DAO | ||
| 16 | + * | ||
| 17 | + * @author HUIHUI | ||
| 18 | + */ | ||
| 19 | +@Repository | ||
| 20 | +public class ErpNoRedisDAO { | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 其它入库 STOCK_IN | ||
| 24 | + */ | ||
| 25 | + public static final String STOCK_IN_NO_PREFIX = "QTRK"; | ||
| 26 | + | ||
| 27 | + @Resource | ||
| 28 | + private StringRedisTemplate stringRedisTemplate; | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 生成序号,使用当前日期,格式为 {PREFIX} + yyyyMMdd + 6 位自增 | ||
| 32 | + * 例如说:QTRK 202109 000001 (没有中间空格) | ||
| 33 | + * | ||
| 34 | + * @param prefix 前缀 | ||
| 35 | + * @return 序号 | ||
| 36 | + */ | ||
| 37 | + public String generate(String prefix) { | ||
| 38 | + // 递增序号 | ||
| 39 | + String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN); | ||
| 40 | + String key = RedisKeyConstants.NO + noPrefix; | ||
| 41 | + Long no = stringRedisTemplate.opsForValue().increment(key); | ||
| 42 | + // 设置过期时间 | ||
| 43 | + stringRedisTemplate.expire(key, Duration.ofMinutes(1L)); | ||
| 44 | + return noPrefix + String.format("%06d", no); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | +} |
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java
| @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; | @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; | ||
| 11 | import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; | 11 | import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; |
| 12 | import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper; | 12 | import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper; |
| 13 | import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper; | 13 | import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper; |
| 14 | +import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; | ||
| 14 | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; | 15 | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| 15 | import cn.iocoder.yudao.module.erp.service.product.ErpProductService; | 16 | import cn.iocoder.yudao.module.erp.service.product.ErpProductService; |
| 16 | import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; | 17 | import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; |
| @@ -45,6 +46,9 @@ public class ErpStockInServiceImpl implements ErpStockInService { | @@ -45,6 +46,9 @@ public class ErpStockInServiceImpl implements ErpStockInService { | ||
| 45 | private ErpStockInItemMapper stockInItemMapper; | 46 | private ErpStockInItemMapper stockInItemMapper; |
| 46 | 47 | ||
| 47 | @Resource | 48 | @Resource |
| 49 | + private ErpNoRedisDAO noRedisDAO; | ||
| 50 | + | ||
| 51 | + @Resource | ||
| 48 | private ErpProductService productService; | 52 | private ErpProductService productService; |
| 49 | @Resource | 53 | @Resource |
| 50 | private ErpWarehouseService warehouseService; | 54 | private ErpWarehouseService warehouseService; |
| @@ -58,10 +62,15 @@ public class ErpStockInServiceImpl implements ErpStockInService { | @@ -58,10 +62,15 @@ public class ErpStockInServiceImpl implements ErpStockInService { | ||
| 58 | List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems()); | 62 | List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems()); |
| 59 | // 1.2 校验供应商 | 63 | // 1.2 校验供应商 |
| 60 | supplierService.validateSupplier(createReqVO.getSupplierId()); | 64 | supplierService.validateSupplier(createReqVO.getSupplierId()); |
| 65 | + // 1.3 | ||
| 66 | + String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_IN_NO_PREFIX); | ||
| 67 | + if (stockInMapper.selectByNo(no) != null) { | ||
| 68 | + throw exception(STOCK_IN_NO_EXISTS); | ||
| 69 | + } | ||
| 61 | 70 | ||
| 62 | // 2.1 插入入库单 | 71 | // 2.1 插入入库单 |
| 63 | ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in | 72 | ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in |
| 64 | - .setStatus(ErpAuditStatus.PROCESS.getStatus()) | 73 | + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()) |
| 65 | .setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add)) | 74 | .setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add)) |
| 66 | .setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); | 75 | .setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); |
| 67 | stockInMapper.insert(stockIn); | 76 | stockInMapper.insert(stockIn); |