Commit 51b53d6ed8979d23cc7cc7399953b05c0c5a3f7b

Authored by puhui999
2 parents 9caaa96e 94247add

Merge remote-tracking branch 'yudao/develop' into develop

# Conflicts:
#	yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ProductServiceImplTest.java
Showing 118 changed files with 7307 additions and 138 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
... ... @@ -288,11 +288,16 @@ public class CollectionUtils {
288 288  
289 289 public static <T, V extends Comparable<? super V>> V getSumValue(List<T> from, Function<T, V> valueFunc,
290 290 BinaryOperator<V> accumulator) {
  291 + return getSumValue(from, valueFunc, accumulator, null);
  292 + }
  293 +
  294 + public static <T, V extends Comparable<? super V>> V getSumValue(List<T> from, Function<T, V> valueFunc,
  295 + BinaryOperator<V> accumulator, V defaultValue) {
291 296 if (CollUtil.isEmpty(from)) {
292   - return null;
  297 + return defaultValue;
293 298 }
294   - assert from.size() > 0; // 断言,避免告警
295   - return from.stream().map(valueFunc).reduce(accumulator).get();
  299 + assert !from.isEmpty(); // 断言,避免告警
  300 + return from.stream().map(valueFunc).filter(Objects::nonNull).reduce(accumulator).orElse(defaultValue);
296 301 }
297 302  
298 303 public static <T> void addIfNotNull(Collection<T> coll, T item) {
... ... @@ -302,8 +307,8 @@ public class CollectionUtils {
302 307 coll.add(item);
303 308 }
304 309  
305   - public static <T> Collection<T> singleton(T deptId) {
306   - return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
  310 + public static <T> Collection<T> singleton(T obj) {
  311 + return obj == null ? Collections.emptyList() : Collections.singleton(obj);
307 312 }
308 313  
309 314 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java
... ... @@ -14,6 +14,11 @@ import java.math.RoundingMode;
14 14 public class MoneyUtils {
15 15  
16 16 /**
  17 + * 金额的小数位数
  18 + */
  19 + private static final int PRICE_SCALE = 2;
  20 +
  21 + /**
17 22 * 计算百分比金额,四舍五入
18 23 *
19 24 * @param price 金额
... ... @@ -86,4 +91,20 @@ public class MoneyUtils {
86 91 return new Money(0, fen).toString();
87 92 }
88 93  
  94 + /**
  95 + * 金额相乘,默认进行四舍五入
  96 + *
  97 + * 位数:{@link #PRICE_SCALE}
  98 + *
  99 + * @param price 金额
  100 + * @param count 数量
  101 + * @return 金额相乘结果
  102 + */
  103 + public static BigDecimal priceMultiply(BigDecimal price, BigDecimal count) {
  104 + if (price == null || count == null) {
  105 + return null;
  106 + }
  107 + return price.multiply(count).setScale(PRICE_SCALE, RoundingMode.HALF_UP);
  108 + }
  109 +
89 110 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java
1 1 package cn.iocoder.yudao.framework.common.util.number;
2 2  
  3 +import cn.hutool.core.util.NumberUtil;
3 4 import cn.hutool.core.util.StrUtil;
4 5  
  6 +import java.math.BigDecimal;
  7 +
5 8 /**
6 9 * 数字的工具类,补全 {@link cn.hutool.core.util.NumberUtil} 的功能
7 10 *
... ... @@ -37,4 +40,21 @@ public class NumberUtils {
37 40 return distance;
38 41 }
39 42  
  43 + /**
  44 + * 提供精确的乘法运算
  45 + *
  46 + * 和 hutool {@link NumberUtil#mul(BigDecimal...)} 的差别是,如果存在 null,则返回 null
  47 + *
  48 + * @param values 多个被乘值
  49 + * @return 积
  50 + */
  51 + public static BigDecimal mul(BigDecimal... values) {
  52 + for (BigDecimal value : values) {
  53 + if (value == null) {
  54 + return null;
  55 + }
  56 + }
  57 + return NumberUtil.mul(values);
  58 + }
  59 +
40 60 }
... ...
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/ErrorCodeConstants.java deleted
1   -package cn.iocoder.yudao.module.erp;
2   -
3   -import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4   -
5   -/**
6   - * ERP 错误码枚举类
7   - * <p>
8   - * erp 系统,使用 1-030-000-000 段
9   - */
10   -public interface ErrorCodeConstants {
11   -
12   - // ========== ERP 产品 1-030-500-000 ==========
13   - ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在");
14   -
15   - // ========== ERP 产品分类 1-030-501-000 ==========
16   - ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_501_000, "产品分类不存在");
17   - ErrorCode PRODUCT_CATEGORY_EXITS_CHILDREN = new ErrorCode(1_030_501_001, "存在存在子产品分类,无法删除");
18   - ErrorCode PRODUCT_CATEGORY_PARENT_NOT_EXITS = new ErrorCode(1_030_501_002,"父级产品分类不存在");
19   - ErrorCode PRODUCT_CATEGORY_PARENT_ERROR = new ErrorCode(1_030_501_003, "不能设置自己为父产品分类");
20   - ErrorCode PRODUCT_CATEGORY_NAME_DUPLICATE = new ErrorCode(1_030_501_004, "已经存在该分类名称的产品分类");
21   - ErrorCode PRODUCT_CATEGORY_PARENT_IS_CHILD = new ErrorCode(1_030_501_005, "不能设置自己的子分类为父分类");
22   -
23   - // ========== ERP 产品单位 1-030-502-000 ==========
24   - ErrorCode PRODUCT_UNIT_NOT_EXISTS = new ErrorCode(1_030_502_000, "产品单位不存在");
25   -
26   -}
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/DictTypeConstants.java
... ... @@ -7,4 +7,7 @@ package cn.iocoder.yudao.module.erp.enums;
7 7 */
8 8 public interface DictTypeConstants {
9 9  
  10 + String AUDIT_STATUS = "erp_audit_status"; // 审核状态
  11 + String STOCK_RECORD_BIZ_TYPE = "erp_stock_record_biz_type"; // 库存明细的业务类型
  12 +
10 13 }
... ...
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpAuditStatus.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.enums;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * ERP 审核状态枚举
  11 + *
  12 + * TODO 芋艿:目前只有待审批、已审批两个状态,未来接入工作流后,会丰富下:待提交(草稿)=》已提交(待审核)=》审核通过、审核不通过;另外,工作流需要支持“反审核”,把工作流退回到原点;
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@RequiredArgsConstructor
  17 +@Getter
  18 +public enum ErpAuditStatus implements IntArrayValuable {
  19 +
  20 + PROCESS(10, "未审核"), // 审核中
  21 + APPROVE(20, "已审核"); // 审核通过
  22 +
  23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpAuditStatus::getStatus).toArray();
  24 +
  25 + /**
  26 + * 状态
  27 + */
  28 + private final Integer status;
  29 + /**
  30 + * 状态名
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public int[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
... ...
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
... ... @@ -9,7 +9,73 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
9 9 */
10 10 public interface ErrorCodeConstants {
11 11  
12   - // ========== 销售订单(1-030-000-000) ==========
13   - ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(1_030_000_000, "销售订单不存在");
  12 + // ========== ERP 供应商(1-030-100-000) ==========
  13 + ErrorCode SUPPLIER_NOT_EXISTS = new ErrorCode(1_030_100_000, "供应商不存在");
  14 + ErrorCode SUPPLIER_NOT_ENABLE = new ErrorCode(1_030_100_000, "供应商({})未启用");
  15 +
  16 + // ========== ERP 客户(1-030-200-000)==========
  17 + ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在");
  18 + ErrorCode CUSTOMER_NOT_ENABLE = new ErrorCode(1_020_200_001, "客户({})未启用");
  19 +
  20 + // ========== ERP 销售订单(1-030-201-000) ==========
  21 + ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(1_020_201_000, "销售订单不存在");
  22 +
  23 + // ========== ERP 仓库 1-030-400-000 ==========
  24 + ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在");
  25 + ErrorCode WAREHOUSE_NOT_ENABLE = new ErrorCode(1_030_400_001, "仓库({})未启用");
  26 +
  27 + // ========== ERP 其它入库单 1-030-401-000 ==========
  28 + ErrorCode STOCK_IN_NOT_EXISTS = new ErrorCode(1_030_401_000, "其它入库单不存在");
  29 + ErrorCode STOCK_IN_DELETE_FAIL_APPROVE = new ErrorCode(1_030_401_001, "其它入库单({})已审核,无法删除");
  30 + ErrorCode STOCK_IN_PROCESS_FAIL = new ErrorCode(1_030_401_002, "反审核失败,只有已审核的入库单才能反审核");
  31 + ErrorCode STOCK_IN_APPROVE_FAIL = new ErrorCode(1_030_401_003, "审核失败,只有未审核的入库单才能审核");
  32 + ErrorCode STOCK_IN_NO_EXISTS = new ErrorCode(1_030_401_004, "生成入库单失败,请重新提交");
  33 + ErrorCode STOCK_IN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_401_005, "其它入库单({})已审核,无法修改");
  34 +
  35 + // ========== ERP 其它出库单 1-030-402-000 ==========
  36 + ErrorCode STOCK_OUT_NOT_EXISTS = new ErrorCode(1_030_402_000, "其它出库单不存在");
  37 + ErrorCode STOCK_OUT_DELETE_FAIL_APPROVE = new ErrorCode(1_030_402_001, "其它出库单({})已审核,无法删除");
  38 + ErrorCode STOCK_OUT_PROCESS_FAIL = new ErrorCode(1_030_402_002, "反审核失败,只有已审核的出库单才能反审核");
  39 + ErrorCode STOCK_OUT_APPROVE_FAIL = new ErrorCode(1_030_402_003, "审核失败,只有未审核的出库单才能审核");
  40 + ErrorCode STOCK_OUT_NO_EXISTS = new ErrorCode(1_030_402_004, "生成出库单失败,请重新提交");
  41 + ErrorCode STOCK_OUT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "其它出库单({})已审核,无法修改");
  42 +
  43 + // ========== ERP 库存调拨单 1-030-403-000 ==========
  44 + ErrorCode STOCK_MOVE_NOT_EXISTS = new ErrorCode(1_030_402_000, "库存调拨单不存在");
  45 + ErrorCode STOCK_MOVE_DELETE_FAIL_APPROVE = new ErrorCode(1_030_402_001, "库存调拨单({})已审核,无法删除");
  46 + ErrorCode STOCK_MOVE_PROCESS_FAIL = new ErrorCode(1_030_402_002, "反审核失败,只有已审核的调拨单才能反审核");
  47 + ErrorCode STOCK_MOVE_APPROVE_FAIL = new ErrorCode(1_030_402_003, "审核失败,只有未审核的调拨单才能审核");
  48 + ErrorCode STOCK_MOVE_NO_EXISTS = new ErrorCode(1_030_402_004, "生成调拨号失败,请重新提交");
  49 + ErrorCode STOCK_MOVE_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "库存调拨单({})已审核,无法修改");
  50 +
  51 + // ========== ERP 库存盘点单 1-030-403-000 ==========
  52 + ErrorCode STOCK_CHECK_NOT_EXISTS = new ErrorCode(1_030_403_000, "库存盘点单不存在");
  53 + ErrorCode STOCK_CHECK_DELETE_FAIL_APPROVE = new ErrorCode(1_030_403_001, "库存盘点单({})已审核,无法删除");
  54 + ErrorCode STOCK_CHECK_PROCESS_FAIL = new ErrorCode(1_030_403_002, "反审核失败,只有已审核的盘点单才能反审核");
  55 + ErrorCode STOCK_CHECK_APPROVE_FAIL = new ErrorCode(1_030_403_003, "审核失败,只有未审核的盘点单才能审核");
  56 + ErrorCode STOCK_CHECK_NO_EXISTS = new ErrorCode(1_030_403_004, "生成盘点号失败,请重新提交");
  57 + ErrorCode STOCK_CHECK_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_403_005, "库存盘点单({})已审核,无法修改");
  58 +
  59 + // ========== ERP 产品库存 1-030-404-000 ==========
  60 + ErrorCode STOCK_COUNT_NEGATIVE = new ErrorCode(1_030_404_000, "操作失败,产品({})所在仓库({})的库存:{},小于变更数量:{}");
  61 + ErrorCode STOCK_COUNT_NEGATIVE2 = new ErrorCode(1_030_404_001, "操作失败,产品({})所在仓库({})的库存不足");
  62 +
  63 + // ========== ERP 产品 1-030-500-000 ==========
  64 + ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在");
  65 + ErrorCode PRODUCT_NOT_ENABLE = new ErrorCode(1_030_500_001, "产品({})未启用");
  66 +
  67 + // ========== ERP 产品分类 1-030-501-000 ==========
  68 + ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_501_000, "产品分类不存在");
  69 + ErrorCode PRODUCT_CATEGORY_EXITS_CHILDREN = new ErrorCode(1_030_501_001, "存在存在子产品分类,无法删除");
  70 + ErrorCode PRODUCT_CATEGORY_PARENT_NOT_EXITS = new ErrorCode(1_030_501_002,"父级产品分类不存在");
  71 + ErrorCode PRODUCT_CATEGORY_PARENT_ERROR = new ErrorCode(1_030_501_003, "不能设置自己为父产品分类");
  72 + ErrorCode PRODUCT_CATEGORY_NAME_DUPLICATE = new ErrorCode(1_030_501_004, "已经存在该分类名称的产品分类");
  73 + ErrorCode PRODUCT_CATEGORY_PARENT_IS_CHILD = new ErrorCode(1_030_501_005, "不能设置自己的子分类为父分类");
  74 + ErrorCode PRODUCT_CATEGORY_EXITS_PRODUCT = new ErrorCode(1_030_502_002, "存在产品使用该分类,无法删除");
  75 +
  76 + // ========== ERP 产品单位 1-030-502-000 ==========
  77 + ErrorCode PRODUCT_UNIT_NOT_EXISTS = new ErrorCode(1_030_502_000, "产品单位不存在");
  78 + ErrorCode PRODUCT_UNIT_NAME_DUPLICATE = new ErrorCode(1_030_502_001, "已存在该名字的产品单位");
  79 + ErrorCode PRODUCT_UNIT_EXITS_PRODUCT = new ErrorCode(1_030_502_002, "存在产品使用该单位,无法删除");
14 80  
15 81 }
... ...
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockRecordBizTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.enums.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * ERP 库存明细 - 业务类型枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@RequiredArgsConstructor
  15 +@Getter
  16 +public enum ErpStockRecordBizTypeEnum implements IntArrayValuable {
  17 +
  18 + OTHER_IN(10, "其它入库"),
  19 + OTHER_IN_CANCEL(11, "其它入库(作废)"),
  20 +
  21 + OTHER_OUT(20, "其它出库"),
  22 + OTHER_OUT_CANCEL(21, "其它出库(作废)"),
  23 +
  24 + MOVE_IN(30, "调拨入库"),
  25 + MOVE_IN_CANCEL(31, "调拨入库(作废)"),
  26 + MOVE_OUT(32, "调拨出库"),
  27 + MOVE_OUT_CANCEL(33, "调拨出库(作废)"),
  28 +
  29 + CHECK_MORE_IN(40, "盘盈入库"),
  30 + CHECK_MORE_IN_CANCEL(41, "盘盈入库(作废)"),
  31 + CHECK_LESS_OUT(42, "盘亏出库"),
  32 + CHECK_LESS_OUT_CANCEL(43, "盘亏出库(作废)"),
  33 + ;
  34 +
  35 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockRecordBizTypeEnum::getType).toArray();
  36 +
  37 + /**
  38 + * 类型
  39 + */
  40 + private final Integer type;
  41 + /**
  42 + * 名字
  43 + */
  44 + private final String name;
  45 +
  46 + @Override
  47 + public int[] array() {
  48 + return ARRAYS;
  49 + }
  50 +
  51 +}
... ...
yudao-module-erp/yudao-module-erp-biz/pom.xml
... ... @@ -51,6 +51,11 @@
51 51 <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
52 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 60 <dependency>
56 61 <groupId>cn.iocoder.boot</groupId>
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductCategoryController.java
1 1 package cn.iocoder.yudao.module.erp.controller.admin.product;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
... ... @@ -23,6 +24,7 @@ import java.io.IOException;
23 24 import java.util.List;
24 25  
25 26 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  27 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
26 28 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
27 29  
28 30 @Tag(name = "管理后台 - ERP 产品分类")
... ... @@ -35,14 +37,14 @@ public class ErpProductCategoryController {
35 37 private ErpProductCategoryService productCategoryService;
36 38  
37 39 @PostMapping("/create")
38   - @Operation(summary = "创建ERP 产品分类")
  40 + @Operation(summary = "创建产品分类")
39 41 @PreAuthorize("@ss.hasPermission('erp:product-category:create')")
40 42 public CommonResult<Long> createProductCategory(@Valid @RequestBody ErpProductCategorySaveReqVO createReqVO) {
41 43 return success(productCategoryService.createProductCategory(createReqVO));
42 44 }
43 45  
44 46 @PutMapping("/update")
45   - @Operation(summary = "更新ERP 产品分类")
  47 + @Operation(summary = "更新产品分类")
46 48 @PreAuthorize("@ss.hasPermission('erp:product-category:update')")
47 49 public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody ErpProductCategorySaveReqVO updateReqVO) {
48 50 productCategoryService.updateProductCategory(updateReqVO);
... ... @@ -50,7 +52,7 @@ public class ErpProductCategoryController {
50 52 }
51 53  
52 54 @DeleteMapping("/delete")
53   - @Operation(summary = "删除ERP 产品分类")
  55 + @Operation(summary = "删除产品分类")
54 56 @Parameter(name = "id", description = "编号", required = true)
55 57 @PreAuthorize("@ss.hasPermission('erp:product-category:delete')")
56 58 public CommonResult<Boolean> deleteProductCategory(@RequestParam("id") Long id) {
... ... @@ -59,31 +61,40 @@ public class ErpProductCategoryController {
59 61 }
60 62  
61 63 @GetMapping("/get")
62   - @Operation(summary = "获得ERP 产品分类")
  64 + @Operation(summary = "获得产品分类")
63 65 @Parameter(name = "id", description = "编号", required = true, example = "1024")
64 66 @PreAuthorize("@ss.hasPermission('erp:product-category:query')")
65 67 public CommonResult<ErpProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) {
66   - ErpProductCategoryDO productCategory = productCategoryService.getProductCategory(id);
67   - return success(BeanUtils.toBean(productCategory, ErpProductCategoryRespVO.class));
  68 + ErpProductCategoryDO category = productCategoryService.getProductCategory(id);
  69 + return success(BeanUtils.toBean(category, ErpProductCategoryRespVO.class));
68 70 }
69 71  
70 72 @GetMapping("/list")
71   - @Operation(summary = "获得ERP 产品分类列表")
  73 + @Operation(summary = "获得产品分类列表")
72 74 @PreAuthorize("@ss.hasPermission('erp:product-category:query')")
73 75 public CommonResult<List<ErpProductCategoryRespVO>> getProductCategoryList(@Valid ErpProductCategoryListReqVO listReqVO) {
74 76 List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(listReqVO);
75 77 return success(BeanUtils.toBean(list, ErpProductCategoryRespVO.class));
76 78 }
77 79  
  80 + @GetMapping("/simple-list")
  81 + @Operation(summary = "获得产品分类精简列表", description = "只包含被开启的分类,主要用于前端的下拉选项")
  82 + public CommonResult<List<ErpProductCategoryRespVO>> getProductCategorySimpleList() {
  83 + List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(
  84 + new ErpProductCategoryListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
  85 + return success(convertList(list, category -> new ErpProductCategoryRespVO()
  86 + .setId(category.getId()).setName(category.getName()).setParentId(category.getParentId())));
  87 + }
  88 +
78 89 @GetMapping("/export-excel")
79   - @Operation(summary = "导出ERP 产品分类 Excel")
  90 + @Operation(summary = "导出产品分类 Excel")
80 91 @PreAuthorize("@ss.hasPermission('erp:product-category:export')")
81 92 @OperateLog(type = EXPORT)
82 93 public void exportProductCategoryExcel(@Valid ErpProductCategoryListReqVO listReqVO,
83 94 HttpServletResponse response) throws IOException {
84 95 List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(listReqVO);
85 96 // 导出 Excel
86   - ExcelUtils.write(response, "ERP 产品分类.xls", "数据", ErpProductCategoryRespVO.class,
  97 + ExcelUtils.write(response, "产品分类.xls", "数据", ErpProductCategoryRespVO.class,
87 98 BeanUtils.toBean(list, ErpProductCategoryRespVO.class));
88 99 }
89 100  
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java
1 1 package cn.iocoder.yudao.module.erp.controller.admin.product;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
8 9 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
9   -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPageReqVO;
10   -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductRespVO;
  10 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
11 12 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO;
12 13 import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
13 14 import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
... ... @@ -25,6 +26,7 @@ import java.io.IOException;
25 26 import java.util.List;
26 27  
27 28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
28 30 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
29 31  
30 32 @Tag(name = "管理后台 - ERP 产品")
... ... @@ -64,30 +66,40 @@ public class ErpProductController {
64 66 @Operation(summary = "获得产品")
65 67 @Parameter(name = "id", description = "编号", required = true, example = "1024")
66 68 @PreAuthorize("@ss.hasPermission('erp:product:query')")
67   - public CommonResult<ProductRespVO> getProduct(@RequestParam("id") Long id) {
  69 + public CommonResult<ErpProductRespVO> getProduct(@RequestParam("id") Long id) {
68 70 ErpProductDO product = productService.getProduct(id);
69   - return success(BeanUtils.toBean(product, ProductRespVO.class));
  71 + return success(BeanUtils.toBean(product, ErpProductRespVO.class));
70 72 }
71 73  
72 74 @GetMapping("/page")
73 75 @Operation(summary = "获得产品分页")
74 76 @PreAuthorize("@ss.hasPermission('erp:product:query')")
75   - public CommonResult<PageResult<ProductRespVO>> getProductPage(@Valid ProductPageReqVO pageReqVO) {
76   - PageResult<ErpProductDO> pageResult = productService.getProductPage(pageReqVO);
77   - return success(BeanUtils.toBean(pageResult, ProductRespVO.class));
  77 + public CommonResult<PageResult<ErpProductRespVO>> getProductPage(@Valid ErpProductPageReqVO pageReqVO) {
  78 + return success(productService.getProductVOPage(pageReqVO));
  79 + }
  80 +
  81 + @GetMapping("/simple-list")
  82 + @Operation(summary = "获得产品精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项")
  83 + public CommonResult<List<ErpProductRespVO>> getProductSimpleList() {
  84 + List<ErpProductRespVO> list = productService.getProductVOListByStatus(CommonStatusEnum.ENABLE.getStatus());
  85 + return success(convertList(list, product -> new ErpProductRespVO().setId(product.getId())
  86 + .setName(product.getName()).setBarCode(product.getBarCode())
  87 + .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
  88 + .setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
  89 + .setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice())));
78 90 }
79 91  
80 92 @GetMapping("/export-excel")
81 93 @Operation(summary = "导出产品 Excel")
82 94 @PreAuthorize("@ss.hasPermission('erp:product:export')")
83 95 @OperateLog(type = EXPORT)
84   - public void exportProductExcel(@Valid ProductPageReqVO pageReqVO,
  96 + public void exportProductExcel(@Valid ErpProductPageReqVO pageReqVO,
85 97 HttpServletResponse response) throws IOException {
86 98 pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
87   - List<ErpProductDO> list = productService.getProductPage(pageReqVO).getList();
  99 + PageResult<ErpProductRespVO> pageResult = productService.getProductVOPage(pageReqVO);
88 100 // 导出 Excel
89   - ExcelUtils.write(response, "产品.xls", "数据", ProductRespVO.class,
90   - BeanUtils.toBean(list, ProductRespVO.class));
  101 + ExcelUtils.write(response, "产品.xls", "数据", ErpProductRespVO.class,
  102 + pageResult.getList());
91 103 }
92 104  
93 105 }
94 106 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductUnitController.java
1 1 package cn.iocoder.yudao.module.erp.controller.admin.product;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
... ... @@ -25,6 +26,7 @@ import java.io.IOException;
25 26 import java.util.List;
26 27  
27 28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
28 30 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
29 31  
30 32 @Tag(name = "管理后台 - ERP 产品单位")
... ... @@ -77,6 +79,13 @@ public class ErpProductUnitController {
77 79 return success(BeanUtils.toBean(pageResult, ErpProductUnitRespVO.class));
78 80 }
79 81  
  82 + @GetMapping("/simple-list")
  83 + @Operation(summary = "获得产品单位精简列表", description = "只包含被开启的单位,主要用于前端的下拉选项")
  84 + public CommonResult<List<ErpProductUnitRespVO>> getProductUnitSimpleList() {
  85 + List<ErpProductUnitDO> list = productUnitService.getProductUnitListByStatus(CommonStatusEnum.ENABLE.getStatus());
  86 + return success(convertList(list, unit -> new ErpProductUnitRespVO().setId(unit.getId()).setName(unit.getName())));
  87 + }
  88 +
80 89 @GetMapping("/export-excel")
81 90 @Operation(summary = "导出产品单位 Excel")
82 91 @PreAuthorize("@ss.hasPermission('erp:product-unit:export')")
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/product/ProductPageReqVO.java renamed to yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/product/ErpProductPageReqVO.java
1 1 package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
2 2  
3 3 import lombok.*;
4   -import java.util.*;
5 4 import io.swagger.v3.oas.annotations.media.Schema;
6 5 import cn.iocoder.yudao.framework.common.pojo.PageParam;
7   -import java.math.BigDecimal;
8 6 import org.springframework.format.annotation.DateTimeFormat;
9 7 import java.time.LocalDateTime;
10 8  
... ... @@ -14,7 +12,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
14 12 @Data
15 13 @EqualsAndHashCode(callSuper = true)
16 14 @ToString(callSuper = true)
17   -public class ProductPageReqVO extends PageParam {
  15 +public class ErpProductPageReqVO extends PageParam {
18 16  
19 17 @Schema(description = "产品名称", example = "李四")
20 18 private String name;
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/product/ProductRespVO.java renamed to yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/product/ErpProductRespVO.java
... ... @@ -11,7 +11,7 @@ import java.time.LocalDateTime;
11 11 @Schema(description = "管理后台 - ERP 产品 Response VO")
12 12 @Data
13 13 @ExcelIgnoreUnannotated
14   -public class ProductRespVO {
  14 +public class ErpProductRespVO {
15 15  
16 16 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15672")
17 17 @ExcelProperty("产品编号")
... ... @@ -26,12 +26,16 @@ public class ProductRespVO {
26 26 private String barCode;
27 27  
28 28 @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11161")
29   - @ExcelProperty("产品分类编号")
30 29 private Long categoryId;
  30 + @Schema(description = "产品分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "水果")
  31 + @ExcelProperty("产品分类")
  32 + private String categoryName;
31 33  
32 34 @Schema(description = "单位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8869")
33   - @ExcelProperty("单位编号")
34   - private Integer unitId;
  35 + private Long unitId;
  36 + @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "个")
  37 + @ExcelProperty("单位")
  38 + private String unitName;
35 39  
36 40 @Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
37 41 @ExcelProperty("产品状态")
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/product/ProductSaveReqVO.java
1 1 package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.*;
5   -import java.util.*;
6   -import jakarta.validation.constraints.*;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
7 8 import java.math.BigDecimal;
8 9  
9 10 @Schema(description = "管理后台 - ERP 产品新增/修改 Request VO")
... ... @@ -27,7 +28,7 @@ public class ProductSaveReqVO {
27 28  
28 29 @Schema(description = "单位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8869")
29 30 @NotNull(message = "单位编号不能为空")
30   - private Integer unitId;
  31 + private Long unitId;
31 32  
32 33 @Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
33 34 @NotNull(message = "产品状态不能为空")
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/unit/ErpProductUnitPageReqVO.java
... ... @@ -5,11 +5,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
5 5 import lombok.Data;
6 6 import lombok.EqualsAndHashCode;
7 7 import lombok.ToString;
8   -import org.springframework.format.annotation.DateTimeFormat;
9   -
10   -import java.time.LocalDateTime;
11   -
12   -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
13 8  
14 9 @Schema(description = "管理后台 - ERP 产品单位分页 Request VO")
15 10 @Data
... ... @@ -23,8 +18,4 @@ public class ErpProductUnitPageReqVO extends PageParam {
23 18 @Schema(description = "单位状态", example = "1")
24 19 private Integer status;
25 20  
26   - @Schema(description = "创建时间")
27   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
28   - private LocalDateTime[] createTime;
29   -
30 21 }
31 22 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/unit/ErpProductUnitRespVO.java
1 1 package cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit;
2 2  
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
3 5 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
4 6 import com.alibaba.excel.annotation.ExcelProperty;
5 7 import io.swagger.v3.oas.annotations.media.Schema;
6   -import jakarta.validation.constraints.NotNull;
7 8 import lombok.Data;
8 9  
9 10 import java.time.LocalDateTime;
... ... @@ -23,7 +24,7 @@ public class ErpProductUnitRespVO {
23 24  
24 25 @Schema(description = "单位状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
25 26 @ExcelProperty("单位状态")
26   - @NotNull(message = "分类排序不能为空")
  27 + @DictFormat(DictTypeConstants.COMMON_STATUS)
27 28 private Integer status;
28 29  
29 30 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/unit/ErpProductUnitSaveReqVO.java
1 1 package cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 5 import io.swagger.v3.oas.annotations.media.Schema;
4 6 import jakarta.validation.constraints.NotEmpty;
5 7 import jakarta.validation.constraints.NotNull;
... ... @@ -18,6 +20,7 @@ public class ErpProductUnitSaveReqVO {
18 20  
19 21 @Schema(description = "单位状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
20 22 @NotNull(message = "单位状态不能为空")
  23 + @InEnum(CommonStatusEnum.class)
21 24 private Integer status;
22 25  
23 26 }
24 27 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpSupplierController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  9 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  10 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierPageReqVO;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierSaveReqVO;
  13 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  14 +import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.tags.Tag;
  18 +import jakarta.annotation.Resource;
  19 +import jakarta.servlet.http.HttpServletResponse;
  20 +import jakarta.validation.Valid;
  21 +import org.springframework.security.access.prepost.PreAuthorize;
  22 +import org.springframework.validation.annotation.Validated;
  23 +import org.springframework.web.bind.annotation.*;
  24 +
  25 +import java.io.IOException;
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  30 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  31 +
  32 +@Tag(name = "管理后台 - ERP 供应商")
  33 +@RestController
  34 +@RequestMapping("/erp/supplier")
  35 +@Validated
  36 +public class ErpSupplierController {
  37 +
  38 + @Resource
  39 + private ErpSupplierService supplierService;
  40 +
  41 + @PostMapping("/create")
  42 + @Operation(summary = "创建供应商")
  43 + @PreAuthorize("@ss.hasPermission('erp:supplier:create')")
  44 + public CommonResult<Long> createSupplier(@Valid @RequestBody ErpSupplierSaveReqVO createReqVO) {
  45 + return success(supplierService.createSupplier(createReqVO));
  46 + }
  47 +
  48 + @PutMapping("/update")
  49 + @Operation(summary = "更新供应商")
  50 + @PreAuthorize("@ss.hasPermission('erp:supplier:update')")
  51 + public CommonResult<Boolean> updateSupplier(@Valid @RequestBody ErpSupplierSaveReqVO updateReqVO) {
  52 + supplierService.updateSupplier(updateReqVO);
  53 + return success(true);
  54 + }
  55 +
  56 + @DeleteMapping("/delete")
  57 + @Operation(summary = "删除供应商")
  58 + @Parameter(name = "id", description = "编号", required = true)
  59 + @PreAuthorize("@ss.hasPermission('erp:supplier:delete')")
  60 + public CommonResult<Boolean> deleteSupplier(@RequestParam("id") Long id) {
  61 + supplierService.deleteSupplier(id);
  62 + return success(true);
  63 + }
  64 +
  65 + @GetMapping("/get")
  66 + @Operation(summary = "获得供应商")
  67 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  68 + @PreAuthorize("@ss.hasPermission('erp:supplier:query')")
  69 + public CommonResult<ErpSupplierRespVO> getSupplier(@RequestParam("id") Long id) {
  70 + ErpSupplierDO supplier = supplierService.getSupplier(id);
  71 + return success(BeanUtils.toBean(supplier, ErpSupplierRespVO.class));
  72 + }
  73 +
  74 + @GetMapping("/page")
  75 + @Operation(summary = "获得供应商分页")
  76 + @PreAuthorize("@ss.hasPermission('erp:supplier:query')")
  77 + public CommonResult<PageResult<ErpSupplierRespVO>> getSupplierPage(@Valid ErpSupplierPageReqVO pageReqVO) {
  78 + PageResult<ErpSupplierDO> pageResult = supplierService.getSupplierPage(pageReqVO);
  79 + return success(BeanUtils.toBean(pageResult, ErpSupplierRespVO.class));
  80 + }
  81 +
  82 + @GetMapping("/simple-list")
  83 + @Operation(summary = "获得供应商精简列表", description = "只包含被开启的供应商,主要用于前端的下拉选项")
  84 + public CommonResult<List<ErpSupplierRespVO>> getSupplierSimpleList() {
  85 + List<ErpSupplierDO> list = supplierService.getSupplierListByStatus(CommonStatusEnum.ENABLE.getStatus());
  86 + return success(convertList(list, supplier -> new ErpSupplierRespVO().setId(supplier.getId()).setName(supplier.getName())));
  87 + }
  88 +
  89 + @GetMapping("/export-excel")
  90 + @Operation(summary = "导出供应商 Excel")
  91 + @PreAuthorize("@ss.hasPermission('erp:supplier:export')")
  92 + @OperateLog(type = EXPORT)
  93 + public void exportSupplierExcel(@Valid ErpSupplierPageReqVO pageReqVO,
  94 + HttpServletResponse response) throws IOException {
  95 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  96 + List<ErpSupplierDO> list = supplierService.getSupplierPage(pageReqVO).getList();
  97 + // 导出 Excel
  98 + ExcelUtils.write(response, "供应商.xls", "数据", ErpSupplierRespVO.class,
  99 + BeanUtils.toBean(list, ErpSupplierRespVO.class));
  100 + }
  101 +
  102 +}
0 103 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/supplier/ErpSupplierPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - ERP 供应商分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class ErpSupplierPageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "供应商名称", example = "芋道源码")
  16 + private String name;
  17 +
  18 + @Schema(description = "手机号码", example = "15601691300")
  19 + private String mobile;
  20 +
  21 + @Schema(description = "联系电话", example = "18818288888")
  22 + private String telephone;
  23 +
  24 +}
0 25 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/supplier/ErpSupplierRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
  6 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  7 +import com.alibaba.excel.annotation.ExcelProperty;
  8 +import io.swagger.v3.oas.annotations.media.Schema;
  9 +import lombok.Data;
  10 +
  11 +import java.math.BigDecimal;
  12 +import java.time.LocalDateTime;
  13 +
  14 +@Schema(description = "管理后台 - ERP 供应商 Response VO")
  15 +@Data
  16 +@ExcelIgnoreUnannotated
  17 +public class ErpSupplierRespVO {
  18 +
  19 + @Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17791")
  20 + @ExcelProperty("供应商编号")
  21 + private Long id;
  22 +
  23 + @Schema(description = "供应商名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
  24 + @ExcelProperty("供应商名称")
  25 + private String name;
  26 +
  27 + @Schema(description = "联系人", example = "芋艿")
  28 + @ExcelProperty("联系人")
  29 + private String contact;
  30 +
  31 + @Schema(description = "手机号码", example = "15601691300")
  32 + @ExcelProperty("手机号码")
  33 + private String mobile;
  34 +
  35 + @Schema(description = "联系电话", example = "18818288888")
  36 + @ExcelProperty("联系电话")
  37 + private String telephone;
  38 +
  39 + @Schema(description = "电子邮箱", example = "76853@qq.com")
  40 + @ExcelProperty("电子邮箱")
  41 + private String email;
  42 +
  43 + @Schema(description = "传真", example = "20 7123 4567")
  44 + @ExcelProperty("传真")
  45 + private String fax;
  46 +
  47 + @Schema(description = "备注", example = "你猜")
  48 + @ExcelProperty("备注")
  49 + private String remark;
  50 +
  51 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  52 + @ExcelProperty(value = "开启状态", converter = DictConvert.class)
  53 + @DictFormat(DictTypeConstants.COMMON_STATUS)
  54 + private Integer status;
  55 +
  56 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  57 + @ExcelProperty("排序")
  58 + private Integer sort;
  59 +
  60 + @Schema(description = "纳税人识别号", example = "91130803MA098BY05W")
  61 + @ExcelProperty("纳税人识别号")
  62 + private String taxNo;
  63 +
  64 + @Schema(description = "税率", example = "10")
  65 + @ExcelProperty("税率")
  66 + private BigDecimal taxPercent;
  67 +
  68 + @Schema(description = "开户行", example = "张三")
  69 + @ExcelProperty("开户行")
  70 + private String bankName;
  71 +
  72 + @Schema(description = "开户账号", example = "622908212277228617")
  73 + @ExcelProperty("开户账号")
  74 + private String bankAccount;
  75 +
  76 + @Schema(description = "开户地址", example = "兴业银行浦东支行")
  77 + @ExcelProperty("开户地址")
  78 + private String bankAddress;
  79 +
  80 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  81 + @ExcelProperty("创建时间")
  82 + private LocalDateTime createTime;
  83 +
  84 +}
0 85 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/supplier/ErpSupplierSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.framework.common.validation.Mobile;
  6 +import cn.iocoder.yudao.framework.common.validation.Telephone;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import jakarta.validation.constraints.Email;
  9 +import jakarta.validation.constraints.NotEmpty;
  10 +import jakarta.validation.constraints.NotNull;
  11 +import lombok.Data;
  12 +
  13 +import java.math.BigDecimal;
  14 +
  15 +@Schema(description = "管理后台 - ERP 供应商新增/修改 Request VO")
  16 +@Data
  17 +public class ErpSupplierSaveReqVO {
  18 +
  19 + @Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17791")
  20 + private Long id;
  21 +
  22 + @Schema(description = "供应商名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
  23 + @NotEmpty(message = "供应商名称不能为空")
  24 + private String name;
  25 +
  26 + @Schema(description = "联系人", example = "芋艿")
  27 + private String contact;
  28 +
  29 + @Schema(description = "手机号码", example = "15601691300")
  30 + @Mobile
  31 + private String mobile;
  32 +
  33 + @Schema(description = "联系电话", example = "18818288888")
  34 + @Telephone
  35 + private String telephone;
  36 +
  37 + @Schema(description = "电子邮箱", example = "76853@qq.com")
  38 + @Email
  39 + private String email;
  40 +
  41 + @Schema(description = "传真", example = "20 7123 4567")
  42 + private String fax;
  43 +
  44 + @Schema(description = "备注", example = "你猜")
  45 + private String remark;
  46 +
  47 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  48 + @NotNull(message = "开启状态不能为空")
  49 + @InEnum(value = CommonStatusEnum.class)
  50 + private Integer status;
  51 +
  52 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  53 + @NotNull(message = "排序不能为空")
  54 + private Integer sort;
  55 +
  56 + @Schema(description = "纳税人识别号", example = "91130803MA098BY05W")
  57 + private String taxNo;
  58 +
  59 + @Schema(description = "税率", example = "10")
  60 + private BigDecimal taxPercent;
  61 +
  62 + @Schema(description = "开户行", example = "张三")
  63 + private String bankName;
  64 +
  65 + @Schema(description = "开户账号", example = "622908212277228617")
  66 + private String bankAccount;
  67 +
  68 + @Schema(description = "开户地址", example = "兴业银行浦东支行")
  69 + private String bankAddress;
  70 +
  71 +}
0 72 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.sale;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  9 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  10 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO;
  13 +import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
  14 +import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.tags.Tag;
  18 +import jakarta.annotation.Resource;
  19 +import jakarta.servlet.http.HttpServletResponse;
  20 +import jakarta.validation.Valid;
  21 +import org.springframework.security.access.prepost.PreAuthorize;
  22 +import org.springframework.validation.annotation.Validated;
  23 +import org.springframework.web.bind.annotation.*;
  24 +
  25 +import java.io.IOException;
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  30 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  31 +
  32 +@Tag(name = "管理后台 - ERP 客户")
  33 +@RestController
  34 +@RequestMapping("/erp/customer")
  35 +@Validated
  36 +public class ErpCustomerController {
  37 +
  38 + @Resource
  39 + private ErpCustomerService customerService;
  40 +
  41 + @PostMapping("/create")
  42 + @Operation(summary = "创建客户")
  43 + @PreAuthorize("@ss.hasPermission('erp:customer:create')")
  44 + public CommonResult<Long> createCustomer(@Valid @RequestBody ErpCustomerSaveReqVO createReqVO) {
  45 + return success(customerService.createCustomer(createReqVO));
  46 + }
  47 +
  48 + @PutMapping("/update")
  49 + @Operation(summary = "更新客户")
  50 + @PreAuthorize("@ss.hasPermission('erp:customer:update')")
  51 + public CommonResult<Boolean> updateCustomer(@Valid @RequestBody ErpCustomerSaveReqVO updateReqVO) {
  52 + customerService.updateCustomer(updateReqVO);
  53 + return success(true);
  54 + }
  55 +
  56 + @DeleteMapping("/delete")
  57 + @Operation(summary = "删除客户")
  58 + @Parameter(name = "id", description = "编号", required = true)
  59 + @PreAuthorize("@ss.hasPermission('erp:customer:delete')")
  60 + public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) {
  61 + customerService.deleteCustomer(id);
  62 + return success(true);
  63 + }
  64 +
  65 + @GetMapping("/get")
  66 + @Operation(summary = "获得客户")
  67 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  68 + @PreAuthorize("@ss.hasPermission('erp:customer:query')")
  69 + public CommonResult<ErpCustomerRespVO> getCustomer(@RequestParam("id") Long id) {
  70 + ErpCustomerDO customer = customerService.getCustomer(id);
  71 + return success(BeanUtils.toBean(customer, ErpCustomerRespVO.class));
  72 + }
  73 +
  74 + @GetMapping("/page")
  75 + @Operation(summary = "获得客户分页")
  76 + @PreAuthorize("@ss.hasPermission('erp:customer:query')")
  77 + public CommonResult<PageResult<ErpCustomerRespVO>> getCustomerPage(@Valid ErpCustomerPageReqVO pageReqVO) {
  78 + PageResult<ErpCustomerDO> pageResult = customerService.getCustomerPage(pageReqVO);
  79 + return success(BeanUtils.toBean(pageResult, ErpCustomerRespVO.class));
  80 + }
  81 +
  82 + @GetMapping("/simple-list")
  83 + @Operation(summary = "获得客户精简列表", description = "只包含被开启的客户,主要用于前端的下拉选项")
  84 + public CommonResult<List<ErpCustomerRespVO>> getCustomerSimpleList() {
  85 + List<ErpCustomerDO> list = customerService.getCustomerListByStatus(CommonStatusEnum.ENABLE.getStatus());
  86 + return success(convertList(list, customer -> new ErpCustomerRespVO().setId(customer.getId()).setName(customer.getName())));
  87 + }
  88 +
  89 + @GetMapping("/export-excel")
  90 + @Operation(summary = "导出客户 Excel")
  91 + @PreAuthorize("@ss.hasPermission('erp:customer:export')")
  92 + @OperateLog(type = EXPORT)
  93 + public void exportCustomerExcel(@Valid ErpCustomerPageReqVO pageReqVO,
  94 + HttpServletResponse response) throws IOException {
  95 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  96 + List<ErpCustomerDO> list = customerService.getCustomerPage(pageReqVO).getList();
  97 + // 导出 Excel
  98 + ExcelUtils.write(response, "客户.xls", "数据", ErpCustomerRespVO.class,
  99 + BeanUtils.toBean(list, ErpCustomerRespVO.class));
  100 + }
  101 +
  102 +}
0 103 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import java.math.BigDecimal;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +import java.time.LocalDateTime;
  10 +
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +@Schema(description = "管理后台 - ERP 客户分页 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class ErpCustomerPageReqVO extends PageParam {
  18 +
  19 + @Schema(description = "客户名称", example = "张三")
  20 + private String name;
  21 +
  22 + @Schema(description = "手机号码", example = "15601691300")
  23 + private String mobile;
  24 +
  25 + @Schema(description = "联系电话", example = "15601691300")
  26 + private String telephone;
  27 +
  28 +}
0 29 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import java.util.*;
  7 +import java.math.BigDecimal;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +import java.time.LocalDateTime;
  10 +import com.alibaba.excel.annotation.*;
  11 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  12 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  13 +
  14 +@Schema(description = "管理后台 - ERP 客户 Response VO")
  15 +@Data
  16 +@ExcelIgnoreUnannotated
  17 +public class ErpCustomerRespVO {
  18 +
  19 + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "27520")
  20 + @ExcelProperty("客户编号")
  21 + private Long id;
  22 +
  23 + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  24 + @ExcelProperty("客户名称")
  25 + private String name;
  26 +
  27 + @Schema(description = "联系人", example = "老王")
  28 + @ExcelProperty("联系人")
  29 + private String contact;
  30 +
  31 + @Schema(description = "手机号码", example = "15601691300")
  32 + @ExcelProperty("手机号码")
  33 + private String mobile;
  34 +
  35 + @Schema(description = "联系电话", example = "15601691300")
  36 + @ExcelProperty("联系电话")
  37 + private String telephone;
  38 +
  39 + @Schema(description = "电子邮箱", example = "7685323@qq.com")
  40 + @ExcelProperty("电子邮箱")
  41 + private String email;
  42 +
  43 + @Schema(description = "传真", example = "20 7123 4567")
  44 + @ExcelProperty("传真")
  45 + private String fax;
  46 +
  47 + @Schema(description = "备注", example = "你猜")
  48 + @ExcelProperty("备注")
  49 + private String remark;
  50 +
  51 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  52 + @ExcelProperty(value = "开启状态", converter = DictConvert.class)
  53 + @DictFormat("common_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
  54 + private Integer status;
  55 +
  56 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  57 + @ExcelProperty("排序")
  58 + private Integer sort;
  59 +
  60 + @Schema(description = "纳税人识别号", example = "91130803MA098BY05W")
  61 + @ExcelProperty("纳税人识别号")
  62 + private String taxNo;
  63 +
  64 + @Schema(description = "税率", example = "10")
  65 + @ExcelProperty("税率")
  66 + private BigDecimal taxPercent;
  67 +
  68 + @Schema(description = "开户行", example = "芋艿")
  69 + @ExcelProperty("开户行")
  70 + private String bankName;
  71 +
  72 + @Schema(description = "开户账号", example = "622908212277228617")
  73 + @ExcelProperty("开户账号")
  74 + private String bankAccount;
  75 +
  76 + @Schema(description = "开户地址", example = "兴业银行浦东支行")
  77 + @ExcelProperty("开户地址")
  78 + private String bankAddress;
  79 +
  80 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  81 + @ExcelProperty("创建时间")
  82 + private LocalDateTime createTime;
  83 +
  84 +}
0 85 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import jakarta.validation.constraints.*;
  7 +import java.math.BigDecimal;
  8 +
  9 +@Schema(description = "管理后台 - ERP 客户新增/修改 Request VO")
  10 +@Data
  11 +public class ErpCustomerSaveReqVO {
  12 +
  13 + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "27520")
  14 + private Long id;
  15 +
  16 + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  17 + @NotEmpty(message = "客户名称不能为空")
  18 + private String name;
  19 +
  20 + @Schema(description = "联系人", example = "老王")
  21 + private String contact;
  22 +
  23 + @Schema(description = "手机号码", example = "15601691300")
  24 + private String mobile;
  25 +
  26 + @Schema(description = "联系电话", example = "15601691300")
  27 + private String telephone;
  28 +
  29 + @Schema(description = "电子邮箱", example = "7685323@qq.com")
  30 + private String email;
  31 +
  32 + @Schema(description = "传真", example = "20 7123 4567")
  33 + private String fax;
  34 +
  35 + @Schema(description = "备注", example = "你猜")
  36 + private String remark;
  37 +
  38 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  39 + @NotNull(message = "开启状态不能为空")
  40 + private Integer status;
  41 +
  42 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  43 + @NotNull(message = "排序不能为空")
  44 + private Integer sort;
  45 +
  46 + @Schema(description = "纳税人识别号", example = "91130803MA098BY05W")
  47 + private String taxNo;
  48 +
  49 + @Schema(description = "税率", example = "10")
  50 + private BigDecimal taxPercent;
  51 +
  52 + @Schema(description = "开户行", example = "芋艿")
  53 + private String bankName;
  54 +
  55 + @Schema(description = "开户账号", example = "622908212277228617")
  56 + private String bankAccount;
  57 +
  58 + @Schema(description = "开户地址", example = "兴业银行浦东支行")
  59 + private String bankAddress;
  60 +
  61 +}
0 62 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO;
  13 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRespVO;
  14 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO;
  16 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
  17 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  18 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockCheckService;
  19 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  20 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  21 +import io.swagger.v3.oas.annotations.Operation;
  22 +import io.swagger.v3.oas.annotations.Parameter;
  23 +import io.swagger.v3.oas.annotations.tags.Tag;
  24 +import jakarta.annotation.Resource;
  25 +import jakarta.servlet.http.HttpServletResponse;
  26 +import jakarta.validation.Valid;
  27 +import org.springframework.security.access.prepost.PreAuthorize;
  28 +import org.springframework.validation.annotation.Validated;
  29 +import org.springframework.web.bind.annotation.*;
  30 +
  31 +import java.io.IOException;
  32 +import java.util.List;
  33 +import java.util.Map;
  34 +
  35 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  36 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  38 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  39 +
  40 +@Tag(name = "管理后台 - ERP 库存调拨单")
  41 +@RestController
  42 +@RequestMapping("/erp/stock-check")
  43 +@Validated
  44 +public class ErpStockCheckController {
  45 +
  46 + @Resource
  47 + private ErpStockCheckService stockCheckService;
  48 + @Resource
  49 + private ErpProductService productService;
  50 +
  51 + @Resource
  52 + private AdminUserApi adminUserApi;
  53 +
  54 + @PostMapping("/create")
  55 + @Operation(summary = "创建库存调拨单")
  56 + @PreAuthorize("@ss.hasPermission('erp:stock-check:create')")
  57 + public CommonResult<Long> createStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO createReqVO) {
  58 + return success(stockCheckService.createStockCheck(createReqVO));
  59 + }
  60 +
  61 + @PutMapping("/update")
  62 + @Operation(summary = "更新库存调拨单")
  63 + @PreAuthorize("@ss.hasPermission('erp:stock-check:update')")
  64 + public CommonResult<Boolean> updateStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO updateReqVO) {
  65 + stockCheckService.updateStockCheck(updateReqVO);
  66 + return success(true);
  67 + }
  68 +
  69 + @PutMapping("/update-status")
  70 + @Operation(summary = "更新库存调拨单的状态")
  71 + @PreAuthorize("@ss.hasPermission('erp:stock-check:update-status')")
  72 + public CommonResult<Boolean> updateStockCheckStatus(@RequestParam("id") Long id,
  73 + @RequestParam("status") Integer status) {
  74 + stockCheckService.updateStockCheckStatus(id, status);
  75 + return success(true);
  76 + }
  77 +
  78 + @DeleteMapping("/delete")
  79 + @Operation(summary = "删除库存调拨单")
  80 + @Parameter(name = "ids", description = "编号数组", required = true)
  81 + @PreAuthorize("@ss.hasPermission('erp:stock-check:delete')")
  82 + public CommonResult<Boolean> deleteStockCheck(@RequestParam("ids") List<Long> ids) {
  83 + stockCheckService.deleteStockCheck(ids);
  84 + return success(true);
  85 + }
  86 +
  87 + @GetMapping("/get")
  88 + @Operation(summary = "获得库存调拨单")
  89 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  90 + @PreAuthorize("@ss.hasPermission('erp:stock-check:query')")
  91 + public CommonResult<ErpStockCheckRespVO> getStockCheck(@RequestParam("id") Long id) {
  92 + ErpStockCheckDO stockCheck = stockCheckService.getStockCheck(id);
  93 + if (stockCheck == null) {
  94 + return success(null);
  95 + }
  96 + List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckId(id);
  97 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  98 + convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId));
  99 + return success(BeanUtils.toBean(stockCheck, ErpStockCheckRespVO.class, stockCheckVO ->
  100 + stockCheckVO.setItems(BeanUtils.toBean(stockCheckItemList, ErpStockCheckRespVO.Item.class, item ->
  101 + MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  102 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))))));
  103 + }
  104 +
  105 + @GetMapping("/page")
  106 + @Operation(summary = "获得库存调拨单分页")
  107 + @PreAuthorize("@ss.hasPermission('erp:stock-check:query')")
  108 + public CommonResult<PageResult<ErpStockCheckRespVO>> getStockCheckPage(@Valid ErpStockCheckPageReqVO pageReqVO) {
  109 + PageResult<ErpStockCheckDO> pageResult = stockCheckService.getStockCheckPage(pageReqVO);
  110 + return success(buildStockCheckVOPageResult(pageResult));
  111 + }
  112 +
  113 + @GetMapping("/export-excel")
  114 + @Operation(summary = "导出库存调拨单 Excel")
  115 + @PreAuthorize("@ss.hasPermission('erp:stock-check:export')")
  116 + @OperateLog(type = EXPORT)
  117 + public void exportStockCheckExcel(@Valid ErpStockCheckPageReqVO pageReqVO,
  118 + HttpServletResponse response) throws IOException {
  119 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  120 + List<ErpStockCheckRespVO> list = buildStockCheckVOPageResult(stockCheckService.getStockCheckPage(pageReqVO)).getList();
  121 + // 导出 Excel
  122 + ExcelUtils.write(response, "库存调拨单.xls", "数据", ErpStockCheckRespVO.class, list);
  123 + }
  124 +
  125 + private PageResult<ErpStockCheckRespVO> buildStockCheckVOPageResult(PageResult<ErpStockCheckDO> pageResult) {
  126 + if (CollUtil.isEmpty(pageResult.getList())) {
  127 + return PageResult.empty(pageResult.getTotal());
  128 + }
  129 + // 1.1 出库项
  130 + List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds(
  131 + convertSet(pageResult.getList(), ErpStockCheckDO::getId));
  132 + Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId);
  133 + // 1.2 商品信息
  134 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  135 + convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId));
  136 + // 1.3 管理员信息
  137 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  138 + convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
  139 + // 2. 开始拼接
  140 + return BeanUtils.toBean(pageResult, ErpStockCheckRespVO.class, stockCheck -> {
  141 + stockCheck.setItems(BeanUtils.toBean(stockCheckItemMap.get(stockCheck.getId()), ErpStockCheckRespVO.Item.class,
  142 + item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  143 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
  144 + stockCheck.setProductNames(CollUtil.join(stockCheck.getItems(), ",", ErpStockCheckRespVO.Item::getProductName));
  145 + MapUtils.findAndThen(userMap, Long.parseLong(stockCheck.getCreator()), user -> stockCheck.setCreatorName(user.getNickname()));
  146 + });
  147 + }
  148 +
  149 +}
0 150 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
  13 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockRespVO;
  14 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
  16 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  17 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
  18 +import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
  19 +import io.swagger.v3.oas.annotations.Operation;
  20 +import io.swagger.v3.oas.annotations.Parameter;
  21 +import io.swagger.v3.oas.annotations.Parameters;
  22 +import io.swagger.v3.oas.annotations.tags.Tag;
  23 +import jakarta.annotation.Resource;
  24 +import jakarta.servlet.http.HttpServletResponse;
  25 +import jakarta.validation.Valid;
  26 +import org.springframework.security.access.prepost.PreAuthorize;
  27 +import org.springframework.validation.annotation.Validated;
  28 +import org.springframework.web.bind.annotation.GetMapping;
  29 +import org.springframework.web.bind.annotation.RequestMapping;
  30 +import org.springframework.web.bind.annotation.RequestParam;
  31 +import org.springframework.web.bind.annotation.RestController;
  32 +
  33 +import java.io.IOException;
  34 +import java.util.List;
  35 +import java.util.Map;
  36 +
  37 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  38 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  39 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  40 +
  41 +@Tag(name = "管理后台 - ERP 产品库存")
  42 +@RestController
  43 +@RequestMapping("/erp/stock")
  44 +@Validated
  45 +public class ErpStockController {
  46 +
  47 + @Resource
  48 + private ErpStockService stockService;
  49 + @Resource
  50 + private ErpProductService productService;
  51 + @Resource
  52 + private ErpWarehouseService warehouseService;
  53 +
  54 + @GetMapping("/get")
  55 + @Operation(summary = "获得产品库存")
  56 + @Parameters({
  57 + @Parameter(name = "id", description = "编号", example = "1"), // 方案一:传递 id
  58 + @Parameter(name = "productId", description = "产品编号", example = "10"), // 方案二:传递 productId + warehouseId
  59 + @Parameter(name = "warehouseId", description = "仓库编号", example = "2")
  60 + })
  61 + @PreAuthorize("@ss.hasPermission('erp:stock:query')")
  62 + public CommonResult<ErpStockRespVO> getStock(@RequestParam(value = "id", required = false) Long id,
  63 + @RequestParam(value = "productId", required = false) Long productId,
  64 + @RequestParam(value = "warehouseId", required = false) Long warehouseId) {
  65 + ErpStockDO stock = id != null ? stockService.getStock(id) : stockService.getStock(productId, warehouseId);
  66 + return success(BeanUtils.toBean(stock, ErpStockRespVO.class));
  67 + }
  68 +
  69 + @GetMapping("/page")
  70 + @Operation(summary = "获得产品库存分页")
  71 + @PreAuthorize("@ss.hasPermission('erp:stock:query')")
  72 + public CommonResult<PageResult<ErpStockRespVO>> getStockPage(@Valid ErpStockPageReqVO pageReqVO) {
  73 + PageResult<ErpStockDO> pageResult = stockService.getStockPage(pageReqVO);
  74 + return success(buildStockVOPageResult(pageResult));
  75 + }
  76 +
  77 + @GetMapping("/export-excel")
  78 + @Operation(summary = "导出产品库存 Excel")
  79 + @PreAuthorize("@ss.hasPermission('erp:stock:export')")
  80 + @OperateLog(type = EXPORT)
  81 + public void exportStockExcel(@Valid ErpStockPageReqVO pageReqVO,
  82 + HttpServletResponse response) throws IOException {
  83 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  84 + List<ErpStockRespVO> list = buildStockVOPageResult(stockService.getStockPage(pageReqVO)).getList();
  85 + // 导出 Excel
  86 + ExcelUtils.write(response, "产品库存.xls", "数据", ErpStockRespVO.class, list);
  87 + }
  88 +
  89 + private PageResult<ErpStockRespVO> buildStockVOPageResult(PageResult<ErpStockDO> pageResult) {
  90 + if (CollUtil.isEmpty(pageResult.getList())) {
  91 + return PageResult.empty(pageResult.getTotal());
  92 + }
  93 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  94 + convertSet(pageResult.getList(), ErpStockDO::getProductId));
  95 + Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
  96 + convertSet(pageResult.getList(), ErpStockDO::getWarehouseId));
  97 + return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> {
  98 + MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName())
  99 + .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName()));
  100 + MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName()));
  101 + });
  102 + }
  103 +
  104 +}
0 105 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO;
  13 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInRespVO;
  14 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
  16 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
  17 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
  18 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  19 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  20 +import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
  21 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService;
  22 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
  23 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  24 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  25 +import io.swagger.v3.oas.annotations.Operation;
  26 +import io.swagger.v3.oas.annotations.Parameter;
  27 +import io.swagger.v3.oas.annotations.tags.Tag;
  28 +import jakarta.annotation.Resource;
  29 +import jakarta.servlet.http.HttpServletResponse;
  30 +import jakarta.validation.Valid;
  31 +import org.springframework.security.access.prepost.PreAuthorize;
  32 +import org.springframework.validation.annotation.Validated;
  33 +import org.springframework.web.bind.annotation.*;
  34 +
  35 +import java.io.IOException;
  36 +import java.math.BigDecimal;
  37 +import java.util.List;
  38 +import java.util.Map;
  39 +
  40 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  41 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
  42 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  43 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  44 +
  45 +@Tag(name = "管理后台 - ERP 其它入库单")
  46 +@RestController
  47 +@RequestMapping("/erp/stock-in")
  48 +@Validated
  49 +public class ErpStockInController {
  50 +
  51 + @Resource
  52 + private ErpStockInService stockInService;
  53 + @Resource
  54 + private ErpStockService stockService;
  55 + @Resource
  56 + private ErpProductService productService;
  57 + @Resource
  58 + private ErpSupplierService supplierService;
  59 +
  60 + @Resource
  61 + private AdminUserApi adminUserApi;
  62 +
  63 + @PostMapping("/create")
  64 + @Operation(summary = "创建其它入库单")
  65 + @PreAuthorize("@ss.hasPermission('erp:stock-in:create')")
  66 + public CommonResult<Long> createStockIn(@Valid @RequestBody ErpStockInSaveReqVO createReqVO) {
  67 + return success(stockInService.createStockIn(createReqVO));
  68 + }
  69 +
  70 + @PutMapping("/update")
  71 + @Operation(summary = "更新其它入库单")
  72 + @PreAuthorize("@ss.hasPermission('erp:stock-in:update')")
  73 + public CommonResult<Boolean> updateStockIn(@Valid @RequestBody ErpStockInSaveReqVO updateReqVO) {
  74 + stockInService.updateStockIn(updateReqVO);
  75 + return success(true);
  76 + }
  77 +
  78 + @PutMapping("/update-status")
  79 + @Operation(summary = "更新其它入库单的状态")
  80 + @PreAuthorize("@ss.hasPermission('erp:stock-in:update-status')")
  81 + public CommonResult<Boolean> updateStockInStatus(@RequestParam("id") Long id,
  82 + @RequestParam("status") Integer status) {
  83 + stockInService.updateStockInStatus(id, status);
  84 + return success(true);
  85 + }
  86 +
  87 + @DeleteMapping("/delete")
  88 + @Operation(summary = "删除其它入库单")
  89 + @Parameter(name = "ids", description = "编号数组", required = true)
  90 + @PreAuthorize("@ss.hasPermission('erp:stock-in:delete')")
  91 + public CommonResult<Boolean> deleteStockIn(@RequestParam("ids") List<Long> ids) {
  92 + stockInService.deleteStockIn(ids);
  93 + return success(true);
  94 + }
  95 +
  96 + @GetMapping("/get")
  97 + @Operation(summary = "获得其它入库单")
  98 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  99 + @PreAuthorize("@ss.hasPermission('erp:stock-in:query')")
  100 + public CommonResult<ErpStockInRespVO> getStockIn(@RequestParam("id") Long id) {
  101 + ErpStockInDO stockIn = stockInService.getStockIn(id);
  102 + if (stockIn == null) {
  103 + return success(null);
  104 + }
  105 + List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInId(id);
  106 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  107 + convertSet(stockInItemList, ErpStockInItemDO::getProductId));
  108 + return success(BeanUtils.toBean(stockIn, ErpStockInRespVO.class, stockInVO ->
  109 + stockInVO.setItems(BeanUtils.toBean(stockInItemList, ErpStockInRespVO.Item.class, item -> {
  110 + ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
  111 + item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
  112 + MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  113 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
  114 + }))));
  115 + }
  116 +
  117 + @GetMapping("/page")
  118 + @Operation(summary = "获得其它入库单分页")
  119 + @PreAuthorize("@ss.hasPermission('erp:stock-in:query')")
  120 + public CommonResult<PageResult<ErpStockInRespVO>> getStockInPage(@Valid ErpStockInPageReqVO pageReqVO) {
  121 + PageResult<ErpStockInDO> pageResult = stockInService.getStockInPage(pageReqVO);
  122 + return success(buildStockInVOPageResult(pageResult));
  123 + }
  124 +
  125 + @GetMapping("/export-excel")
  126 + @Operation(summary = "导出其它入库单 Excel")
  127 + @PreAuthorize("@ss.hasPermission('erp:stock-in:export')")
  128 + @OperateLog(type = EXPORT)
  129 + public void exportStockInExcel(@Valid ErpStockInPageReqVO pageReqVO,
  130 + HttpServletResponse response) throws IOException {
  131 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  132 + List<ErpStockInRespVO> list = buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)).getList();
  133 + // 导出 Excel
  134 + ExcelUtils.write(response, "其它入库单.xls", "数据", ErpStockInRespVO.class, list);
  135 + }
  136 +
  137 + private PageResult<ErpStockInRespVO> buildStockInVOPageResult(PageResult<ErpStockInDO> pageResult) {
  138 + if (CollUtil.isEmpty(pageResult.getList())) {
  139 + return PageResult.empty(pageResult.getTotal());
  140 + }
  141 + // 1.1 入库项
  142 + List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInIds(
  143 + convertSet(pageResult.getList(), ErpStockInDO::getId));
  144 + Map<Long, List<ErpStockInItemDO>> stockInItemMap = convertMultiMap(stockInItemList, ErpStockInItemDO::getInId);
  145 + // 1.2 商品信息
  146 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  147 + convertSet(stockInItemList, ErpStockInItemDO::getProductId));
  148 + // 1.3 供应商信息
  149 + Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(
  150 + convertSet(pageResult.getList(), ErpStockInDO::getSupplierId));
  151 + // 1.4 管理员信息
  152 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  153 + convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
  154 + // 2. 开始拼接
  155 + return BeanUtils.toBean(pageResult, ErpStockInRespVO.class, stockIn -> {
  156 + stockIn.setItems(BeanUtils.toBean(stockInItemMap.get(stockIn.getId()), ErpStockInRespVO.Item.class,
  157 + item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  158 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
  159 + stockIn.setProductNames(CollUtil.join(stockIn.getItems(), ",", ErpStockInRespVO.Item::getProductName));
  160 + MapUtils.findAndThen(supplierMap, stockIn.getSupplierId(), supplier -> stockIn.setSupplierName(supplier.getName()));
  161 + MapUtils.findAndThen(userMap, Long.parseLong(stockIn.getCreator()), user -> stockIn.setCreatorName(user.getNickname()));
  162 + });
  163 + }
  164 +
  165 +}
0 166 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO;
  13 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveRespVO;
  14 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
  16 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO;
  17 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO;
  18 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  19 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockMoveService;
  20 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
  21 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  22 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  23 +import io.swagger.v3.oas.annotations.Operation;
  24 +import io.swagger.v3.oas.annotations.Parameter;
  25 +import io.swagger.v3.oas.annotations.tags.Tag;
  26 +import jakarta.annotation.Resource;
  27 +import jakarta.servlet.http.HttpServletResponse;
  28 +import jakarta.validation.Valid;
  29 +import org.springframework.security.access.prepost.PreAuthorize;
  30 +import org.springframework.validation.annotation.Validated;
  31 +import org.springframework.web.bind.annotation.*;
  32 +
  33 +import java.io.IOException;
  34 +import java.math.BigDecimal;
  35 +import java.util.List;
  36 +import java.util.Map;
  37 +
  38 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  39 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
  40 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  41 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  42 +
  43 +@Tag(name = "管理后台 - ERP 库存调拨单")
  44 +@RestController
  45 +@RequestMapping("/erp/stock-move")
  46 +@Validated
  47 +public class ErpStockMoveController {
  48 +
  49 + @Resource
  50 + private ErpStockMoveService stockMoveService;
  51 + @Resource
  52 + private ErpStockService stockService;
  53 + @Resource
  54 + private ErpProductService productService;
  55 +
  56 + @Resource
  57 + private AdminUserApi adminUserApi;
  58 +
  59 + @PostMapping("/create")
  60 + @Operation(summary = "创建库存调拨单")
  61 + @PreAuthorize("@ss.hasPermission('erp:stock-move:create')")
  62 + public CommonResult<Long> createStockMove(@Valid @RequestBody ErpStockMoveSaveReqVO createReqVO) {
  63 + return success(stockMoveService.createStockMove(createReqVO));
  64 + }
  65 +
  66 + @PutMapping("/update")
  67 + @Operation(summary = "更新库存调拨单")
  68 + @PreAuthorize("@ss.hasPermission('erp:stock-move:update')")
  69 + public CommonResult<Boolean> updateStockMove(@Valid @RequestBody ErpStockMoveSaveReqVO updateReqVO) {
  70 + stockMoveService.updateStockMove(updateReqVO);
  71 + return success(true);
  72 + }
  73 +
  74 + @PutMapping("/update-status")
  75 + @Operation(summary = "更新库存调拨单的状态")
  76 + @PreAuthorize("@ss.hasPermission('erp:stock-move:update-status')")
  77 + public CommonResult<Boolean> updateStockMoveStatus(@RequestParam("id") Long id,
  78 + @RequestParam("status") Integer status) {
  79 + stockMoveService.updateStockMoveStatus(id, status);
  80 + return success(true);
  81 + }
  82 +
  83 + @DeleteMapping("/delete")
  84 + @Operation(summary = "删除库存调拨单")
  85 + @Parameter(name = "ids", description = "编号数组", required = true)
  86 + @PreAuthorize("@ss.hasPermission('erp:stock-move:delete')")
  87 + public CommonResult<Boolean> deleteStockMove(@RequestParam("ids") List<Long> ids) {
  88 + stockMoveService.deleteStockMove(ids);
  89 + return success(true);
  90 + }
  91 +
  92 + @GetMapping("/get")
  93 + @Operation(summary = "获得库存调拨单")
  94 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  95 + @PreAuthorize("@ss.hasPermission('erp:stock-move:query')")
  96 + public CommonResult<ErpStockMoveRespVO> getStockMove(@RequestParam("id") Long id) {
  97 + ErpStockMoveDO stockMove = stockMoveService.getStockMove(id);
  98 + if (stockMove == null) {
  99 + return success(null);
  100 + }
  101 + List<ErpStockMoveItemDO> stockMoveItemList = stockMoveService.getStockMoveItemListByMoveId(id);
  102 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  103 + convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId));
  104 + return success(BeanUtils.toBean(stockMove, ErpStockMoveRespVO.class, stockMoveVO ->
  105 + stockMoveVO.setItems(BeanUtils.toBean(stockMoveItemList, ErpStockMoveRespVO.Item.class, item -> {
  106 + ErpStockDO stock = stockService.getStock(item.getProductId(), item.getFromWarehouseId());
  107 + item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
  108 + MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  109 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
  110 + }))));
  111 + }
  112 +
  113 + @GetMapping("/page")
  114 + @Operation(summary = "获得库存调拨单分页")
  115 + @PreAuthorize("@ss.hasPermission('erp:stock-move:query')")
  116 + public CommonResult<PageResult<ErpStockMoveRespVO>> getStockMovePage(@Valid ErpStockMovePageReqVO pageReqVO) {
  117 + PageResult<ErpStockMoveDO> pageResult = stockMoveService.getStockMovePage(pageReqVO);
  118 + return success(buildStockMoveVOPageResult(pageResult));
  119 + }
  120 +
  121 + @GetMapping("/export-excel")
  122 + @Operation(summary = "导出库存调拨单 Excel")
  123 + @PreAuthorize("@ss.hasPermission('erp:stock-move:export')")
  124 + @OperateLog(type = EXPORT)
  125 + public void exportStockMoveExcel(@Valid ErpStockMovePageReqVO pageReqVO,
  126 + HttpServletResponse response) throws IOException {
  127 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  128 + List<ErpStockMoveRespVO> list = buildStockMoveVOPageResult(stockMoveService.getStockMovePage(pageReqVO)).getList();
  129 + // 导出 Excel
  130 + ExcelUtils.write(response, "库存调拨单.xls", "数据", ErpStockMoveRespVO.class, list);
  131 + }
  132 +
  133 + private PageResult<ErpStockMoveRespVO> buildStockMoveVOPageResult(PageResult<ErpStockMoveDO> pageResult) {
  134 + if (CollUtil.isEmpty(pageResult.getList())) {
  135 + return PageResult.empty(pageResult.getTotal());
  136 + }
  137 + // 1.1 出库项
  138 + List<ErpStockMoveItemDO> stockMoveItemList = stockMoveService.getStockMoveItemListByMoveIds(
  139 + convertSet(pageResult.getList(), ErpStockMoveDO::getId));
  140 + Map<Long, List<ErpStockMoveItemDO>> stockMoveItemMap = convertMultiMap(stockMoveItemList, ErpStockMoveItemDO::getMoveId);
  141 + // 1.2 商品信息
  142 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  143 + convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId));
  144 + // 1.3 TODO 芋艿:搞仓库信息
  145 + // 1.4 管理员信息
  146 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  147 + convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
  148 + // 2. 开始拼接
  149 + return BeanUtils.toBean(pageResult, ErpStockMoveRespVO.class, stockMove -> {
  150 + stockMove.setItems(BeanUtils.toBean(stockMoveItemMap.get(stockMove.getId()), ErpStockMoveRespVO.Item.class,
  151 + item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  152 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
  153 + stockMove.setProductNames(CollUtil.join(stockMove.getItems(), ",", ErpStockMoveRespVO.Item::getProductName));
  154 + // TODO 芋艿:
  155 +// MapUtils.findAndThen(customerMap, stockMove.getCustomerId(), supplier -> stockMove.setCustomerName(supplier.getName()));
  156 + MapUtils.findAndThen(userMap, Long.parseLong(stockMove.getCreator()), user -> stockMove.setCreatorName(user.getNickname()));
  157 + });
  158 + }
  159 +
  160 +}
0 161 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO;
  13 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutRespVO;
  14 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
  16 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
  17 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
  18 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
  19 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  20 +import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
  21 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockOutService;
  22 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
  23 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  24 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  25 +import io.swagger.v3.oas.annotations.Operation;
  26 +import io.swagger.v3.oas.annotations.Parameter;
  27 +import io.swagger.v3.oas.annotations.tags.Tag;
  28 +import jakarta.annotation.Resource;
  29 +import jakarta.servlet.http.HttpServletResponse;
  30 +import jakarta.validation.Valid;
  31 +import org.springframework.security.access.prepost.PreAuthorize;
  32 +import org.springframework.validation.annotation.Validated;
  33 +import org.springframework.web.bind.annotation.*;
  34 +
  35 +import java.io.IOException;
  36 +import java.math.BigDecimal;
  37 +import java.util.List;
  38 +import java.util.Map;
  39 +
  40 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  41 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
  42 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  43 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  44 +
  45 +@Tag(name = "管理后台 - ERP 其它出库单")
  46 +@RestController
  47 +@RequestMapping("/erp/stock-out")
  48 +@Validated
  49 +public class ErpStockOutController {
  50 +
  51 + @Resource
  52 + private ErpStockOutService stockOutService;
  53 + @Resource
  54 + private ErpStockService stockService;
  55 + @Resource
  56 + private ErpProductService productService;
  57 + @Resource
  58 + private ErpCustomerService customerService;
  59 +
  60 + @Resource
  61 + private AdminUserApi adminUserApi;
  62 +
  63 + @PostMapping("/create")
  64 + @Operation(summary = "创建其它出库单")
  65 + @PreAuthorize("@ss.hasPermission('erp:stock-out:create')")
  66 + public CommonResult<Long> createStockOut(@Valid @RequestBody ErpStockOutSaveReqVO createReqVO) {
  67 + return success(stockOutService.createStockOut(createReqVO));
  68 + }
  69 +
  70 + @PutMapping("/update")
  71 + @Operation(summary = "更新其它出库单")
  72 + @PreAuthorize("@ss.hasPermission('erp:stock-out:update')")
  73 + public CommonResult<Boolean> updateStockOut(@Valid @RequestBody ErpStockOutSaveReqVO updateReqVO) {
  74 + stockOutService.updateStockOut(updateReqVO);
  75 + return success(true);
  76 + }
  77 +
  78 + @PutMapping("/update-status")
  79 + @Operation(summary = "更新其它出库单的状态")
  80 + @PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')")
  81 + public CommonResult<Boolean> updateStockOutStatus(@RequestParam("id") Long id,
  82 + @RequestParam("status") Integer status) {
  83 + stockOutService.updateStockOutStatus(id, status);
  84 + return success(true);
  85 + }
  86 +
  87 + @DeleteMapping("/delete")
  88 + @Operation(summary = "删除其它出库单")
  89 + @Parameter(name = "ids", description = "编号数组", required = true)
  90 + @PreAuthorize("@ss.hasPermission('erp:stock-out:delete')")
  91 + public CommonResult<Boolean> deleteStockOut(@RequestParam("ids") List<Long> ids) {
  92 + stockOutService.deleteStockOut(ids);
  93 + return success(true);
  94 + }
  95 +
  96 + @GetMapping("/get")
  97 + @Operation(summary = "获得其它出库单")
  98 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  99 + @PreAuthorize("@ss.hasPermission('erp:stock-out:query')")
  100 + public CommonResult<ErpStockOutRespVO> getStockOut(@RequestParam("id") Long id) {
  101 + ErpStockOutDO stockOut = stockOutService.getStockOut(id);
  102 + if (stockOut == null) {
  103 + return success(null);
  104 + }
  105 + List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutId(id);
  106 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  107 + convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
  108 + return success(BeanUtils.toBean(stockOut, ErpStockOutRespVO.class, stockOutVO ->
  109 + stockOutVO.setItems(BeanUtils.toBean(stockOutItemList, ErpStockOutRespVO.Item.class, item -> {
  110 + ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
  111 + item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
  112 + MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  113 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
  114 + }))));
  115 + }
  116 +
  117 + @GetMapping("/page")
  118 + @Operation(summary = "获得其它出库单分页")
  119 + @PreAuthorize("@ss.hasPermission('erp:stock-out:query')")
  120 + public CommonResult<PageResult<ErpStockOutRespVO>> getStockOutPage(@Valid ErpStockOutPageReqVO pageReqVO) {
  121 + PageResult<ErpStockOutDO> pageResult = stockOutService.getStockOutPage(pageReqVO);
  122 + return success(buildStockOutVOPageResult(pageResult));
  123 + }
  124 +
  125 + @GetMapping("/export-excel")
  126 + @Operation(summary = "导出其它出库单 Excel")
  127 + @PreAuthorize("@ss.hasPermission('erp:stock-out:export')")
  128 + @OperateLog(type = EXPORT)
  129 + public void exportStockOutExcel(@Valid ErpStockOutPageReqVO pageReqVO,
  130 + HttpServletResponse response) throws IOException {
  131 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  132 + List<ErpStockOutRespVO> list = buildStockOutVOPageResult(stockOutService.getStockOutPage(pageReqVO)).getList();
  133 + // 导出 Excel
  134 + ExcelUtils.write(response, "其它出库单.xls", "数据", ErpStockOutRespVO.class, list);
  135 + }
  136 +
  137 + private PageResult<ErpStockOutRespVO> buildStockOutVOPageResult(PageResult<ErpStockOutDO> pageResult) {
  138 + if (CollUtil.isEmpty(pageResult.getList())) {
  139 + return PageResult.empty(pageResult.getTotal());
  140 + }
  141 + // 1.1 出库项
  142 + List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutIds(
  143 + convertSet(pageResult.getList(), ErpStockOutDO::getId));
  144 + Map<Long, List<ErpStockOutItemDO>> stockOutItemMap = convertMultiMap(stockOutItemList, ErpStockOutItemDO::getOutId);
  145 + // 1.2 商品信息
  146 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  147 + convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
  148 + // 1.3 客户信息
  149 + Map<Long, ErpCustomerDO> customerMap = customerService.getCustomerMap(
  150 + convertSet(pageResult.getList(), ErpStockOutDO::getCustomerId));
  151 + // 1.4 管理员信息
  152 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  153 + convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
  154 + // 2. 开始拼接
  155 + return BeanUtils.toBean(pageResult, ErpStockOutRespVO.class, stockOut -> {
  156 + stockOut.setItems(BeanUtils.toBean(stockOutItemMap.get(stockOut.getId()), ErpStockOutRespVO.Item.class,
  157 + item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  158 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
  159 + stockOut.setProductNames(CollUtil.join(stockOut.getItems(), ",", ErpStockOutRespVO.Item::getProductName));
  160 + MapUtils.findAndThen(customerMap, stockOut.getCustomerId(), supplier -> stockOut.setCustomerName(supplier.getName()));
  161 + MapUtils.findAndThen(userMap, Long.parseLong(stockOut.getCreator()), user -> stockOut.setCreatorName(user.getNickname()));
  162 + });
  163 + }
  164 +
  165 +}
0 166 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockRecordController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO;
  13 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordRespVO;
  14 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
  16 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  17 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService;
  18 +import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
  19 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  20 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  21 +import io.swagger.v3.oas.annotations.Operation;
  22 +import io.swagger.v3.oas.annotations.Parameter;
  23 +import io.swagger.v3.oas.annotations.tags.Tag;
  24 +import jakarta.annotation.Resource;
  25 +import jakarta.servlet.http.HttpServletResponse;
  26 +import jakarta.validation.Valid;
  27 +import org.springframework.security.access.prepost.PreAuthorize;
  28 +import org.springframework.validation.annotation.Validated;
  29 +import org.springframework.web.bind.annotation.GetMapping;
  30 +import org.springframework.web.bind.annotation.RequestMapping;
  31 +import org.springframework.web.bind.annotation.RequestParam;
  32 +import org.springframework.web.bind.annotation.RestController;
  33 +
  34 +import java.io.IOException;
  35 +import java.util.List;
  36 +import java.util.Map;
  37 +
  38 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  39 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  40 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  41 +
  42 +@Tag(name = "管理后台 - ERP 产品库存明细")
  43 +@RestController
  44 +@RequestMapping("/erp/stock-record")
  45 +@Validated
  46 +public class ErpStockRecordController {
  47 +
  48 + @Resource
  49 + private ErpStockRecordService stockRecordService;
  50 + @Resource
  51 + private ErpProductService productService;
  52 + @Resource
  53 + private ErpWarehouseService warehouseService;
  54 +
  55 + @Resource
  56 + private AdminUserApi adminUserApi;
  57 +
  58 + @GetMapping("/get")
  59 + @Operation(summary = "获得产品库存明细")
  60 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  61 + @PreAuthorize("@ss.hasPermission('erp:stock-record:query')")
  62 + public CommonResult<ErpStockRecordRespVO> getStockRecord(@RequestParam("id") Long id) {
  63 + ErpStockRecordDO stockRecord = stockRecordService.getStockRecord(id);
  64 + return success(BeanUtils.toBean(stockRecord, ErpStockRecordRespVO.class));
  65 + }
  66 +
  67 + @GetMapping("/page")
  68 + @Operation(summary = "获得产品库存明细分页")
  69 + @PreAuthorize("@ss.hasPermission('erp:stock-record:query')")
  70 + public CommonResult<PageResult<ErpStockRecordRespVO>> getStockRecordPage(@Valid ErpStockRecordPageReqVO pageReqVO) {
  71 + PageResult<ErpStockRecordDO> pageResult = stockRecordService.getStockRecordPage(pageReqVO);
  72 + return success(buildStockRecrodVOPageResult(pageResult));
  73 + }
  74 +
  75 + @GetMapping("/export-excel")
  76 + @Operation(summary = "导出产品库存明细 Excel")
  77 + @PreAuthorize("@ss.hasPermission('erp:stock-record:export')")
  78 + @OperateLog(type = EXPORT)
  79 + public void exportStockRecordExcel(@Valid ErpStockRecordPageReqVO pageReqVO,
  80 + HttpServletResponse response) throws IOException {
  81 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  82 + List<ErpStockRecordRespVO> list = buildStockRecrodVOPageResult(stockRecordService.getStockRecordPage(pageReqVO)).getList();
  83 + // 导出 Excel
  84 + ExcelUtils.write(response, "产品库存明细.xls", "数据", ErpStockRecordRespVO.class, list);
  85 + }
  86 +
  87 + private PageResult<ErpStockRecordRespVO> buildStockRecrodVOPageResult(PageResult<ErpStockRecordDO> pageResult) {
  88 + if (CollUtil.isEmpty(pageResult.getList())) {
  89 + return PageResult.empty(pageResult.getTotal());
  90 + }
  91 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  92 + convertSet(pageResult.getList(), ErpStockRecordDO::getProductId));
  93 + Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
  94 + convertSet(pageResult.getList(), ErpStockRecordDO::getWarehouseId));
  95 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  96 + convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
  97 + return BeanUtils.toBean(pageResult, ErpStockRecordRespVO.class, stock -> {
  98 + MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName())
  99 + .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName()));
  100 + MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName()));
  101 + MapUtils.findAndThen(userMap, Long.parseLong(stock.getCreator()), user -> stock.setCreatorName(user.getNickname()));
  102 + });
  103 + }
  104 +
  105 +}
0 106 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpWarehouseController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  9 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  10 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.ErpWarehouseSaveReqVO;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseRespVO;
  13 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
  14 +import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.Parameters;
  18 +import io.swagger.v3.oas.annotations.tags.Tag;
  19 +import jakarta.annotation.Resource;
  20 +import jakarta.servlet.http.HttpServletResponse;
  21 +import jakarta.validation.Valid;
  22 +import org.springframework.security.access.prepost.PreAuthorize;
  23 +import org.springframework.validation.annotation.Validated;
  24 +import org.springframework.web.bind.annotation.*;
  25 +
  26 +import java.io.IOException;
  27 +import java.util.List;
  28 +
  29 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  30 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  31 +
  32 +@Tag(name = "管理后台 - ERP 仓库")
  33 +@RestController
  34 +@RequestMapping("/erp/warehouse")
  35 +@Validated
  36 +public class ErpWarehouseController {
  37 +
  38 + @Resource
  39 + private ErpWarehouseService warehouseService;
  40 +
  41 + @PostMapping("/create")
  42 + @Operation(summary = "创建仓库")
  43 + @PreAuthorize("@ss.hasPermission('erp:warehouse:create')")
  44 + public CommonResult<Long> createWarehouse(@Valid @RequestBody ErpWarehouseSaveReqVO createReqVO) {
  45 + return success(warehouseService.createWarehouse(createReqVO));
  46 + }
  47 +
  48 + @PutMapping("/update")
  49 + @Operation(summary = "更新仓库")
  50 + @PreAuthorize("@ss.hasPermission('erp:warehouse:update')")
  51 + public CommonResult<Boolean> updateWarehouse(@Valid @RequestBody ErpWarehouseSaveReqVO updateReqVO) {
  52 + warehouseService.updateWarehouse(updateReqVO);
  53 + return success(true);
  54 + }
  55 +
  56 + @PutMapping("/update-default-status")
  57 + @Operation(summary = "更新仓库默认状态")
  58 + @Parameters({
  59 + @Parameter(name = "id", description = "编号", required = true),
  60 + @Parameter(name = "status", description = "状态", required = true)
  61 + })
  62 + public CommonResult<Boolean> updateWarehouseDefaultStatus(@RequestParam("id") Long id,
  63 + @RequestParam("defaultStatus") Boolean defaultStatus) {
  64 + warehouseService.updateWarehouseDefaultStatus(id, defaultStatus);
  65 + return success(true);
  66 + }
  67 +
  68 + @DeleteMapping("/delete")
  69 + @Operation(summary = "删除仓库")
  70 + @Parameter(name = "id", description = "编号", required = true)
  71 + @PreAuthorize("@ss.hasPermission('erp:warehouse:delete')")
  72 + public CommonResult<Boolean> deleteWarehouse(@RequestParam("id") Long id) {
  73 + warehouseService.deleteWarehouse(id);
  74 + return success(true);
  75 + }
  76 +
  77 + @GetMapping("/get")
  78 + @Operation(summary = "获得仓库")
  79 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  80 + @PreAuthorize("@ss.hasPermission('erp:warehouse:query')")
  81 + public CommonResult<ErpWarehouseRespVO> getWarehouse(@RequestParam("id") Long id) {
  82 + ErpWarehouseDO warehouse = warehouseService.getWarehouse(id);
  83 + return success(BeanUtils.toBean(warehouse, ErpWarehouseRespVO.class));
  84 + }
  85 +
  86 + @GetMapping("/page")
  87 + @Operation(summary = "获得仓库分页")
  88 + @PreAuthorize("@ss.hasPermission('erp:warehouse:query')")
  89 + public CommonResult<PageResult<ErpWarehouseRespVO>> getWarehousePage(@Valid ErpWarehousePageReqVO pageReqVO) {
  90 + PageResult<ErpWarehouseDO> pageResult = warehouseService.getWarehousePage(pageReqVO);
  91 + return success(BeanUtils.toBean(pageResult, ErpWarehouseRespVO.class));
  92 + }
  93 +
  94 + @GetMapping("/simple-list")
  95 + @Operation(summary = "获得仓库精简列表", description = "只包含被开启的仓库,主要用于前端的下拉选项")
  96 + public CommonResult<List<ErpWarehouseRespVO>> getWarehouseSimpleList() {
  97 + List<ErpWarehouseDO> list = warehouseService.getWarehouseListByStatus(CommonStatusEnum.ENABLE.getStatus());
  98 + return success(BeanUtils.toBean(list, ErpWarehouseRespVO.class));
  99 + }
  100 +
  101 + @GetMapping("/export-excel")
  102 + @Operation(summary = "导出仓库 Excel")
  103 + @PreAuthorize("@ss.hasPermission('erp:warehouse:export')")
  104 + @OperateLog(type = EXPORT)
  105 + public void exportWarehouseExcel(@Valid ErpWarehousePageReqVO pageReqVO,
  106 + HttpServletResponse response) throws IOException {
  107 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  108 + List<ErpWarehouseDO> list = warehouseService.getWarehousePage(pageReqVO).getList();
  109 + // 导出 Excel
  110 + ExcelUtils.write(response, "仓库.xls", "数据", ErpWarehouseRespVO.class,
  111 + BeanUtils.toBean(list, ErpWarehouseRespVO.class));
  112 + }
  113 +
  114 +}
0 115 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +import org.springframework.format.annotation.DateTimeFormat;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@Schema(description = "管理后台 - ERP 库存盘点单分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class ErpStockCheckPageReqVO extends PageParam {
  21 +
  22 + @Schema(description = "盘点单号", example = "S123")
  23 + private String no;
  24 +
  25 + @Schema(description = "仓库编号", example = "3113")
  26 + private Long warehouseId;
  27 +
  28 + @Schema(description = "盘点时间")
  29 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  30 + private LocalDateTime[] checkTime;
  31 +
  32 + @Schema(description = "状态", example = "10")
  33 + @InEnum(ErpAuditStatus.class)
  34 + private Integer status;
  35 +
  36 + @Schema(description = "备注", example = "随便")
  37 + private String remark;
  38 +
  39 + @Schema(description = "创建者")
  40 + private String creator;
  41 +
  42 + @Schema(description = "产品编号", example = "1")
  43 + private Long productId;
  44 +
  45 +}
0 46 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import jakarta.validation.constraints.NotNull;
  9 +import lombok.Data;
  10 +
  11 +import java.math.BigDecimal;
  12 +import java.time.LocalDateTime;
  13 +import java.util.List;
  14 +
  15 +import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.AUDIT_STATUS;
  16 +
  17 +@Schema(description = "管理后台 - ERP 库存盘点单 Response VO")
  18 +@Data
  19 +@ExcelIgnoreUnannotated
  20 +public class ErpStockCheckRespVO {
  21 +
  22 + @Schema(description = "盘点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  23 + @ExcelProperty("盘点编号")
  24 + private Long id;
  25 +
  26 + @Schema(description = "盘点单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "S123")
  27 + @ExcelProperty("盘点单号")
  28 + private String no;
  29 +
  30 + @Schema(description = "盘点时间", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + @ExcelProperty("盘点时间")
  32 + private LocalDateTime checkTime;
  33 +
  34 + @Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
  35 + @ExcelProperty("合计数量")
  36 + private BigDecimal totalCount;
  37 +
  38 + @Schema(description = "合计金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
  39 + @ExcelProperty("合计金额")
  40 + private BigDecimal totalPrice;
  41 +
  42 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  43 + @ExcelProperty(value = "状态", converter = DictConvert.class)
  44 + @DictFormat(AUDIT_STATUS)
  45 + private Integer status;
  46 +
  47 + @Schema(description = "备注", example = "随便")
  48 + @ExcelProperty("备注")
  49 + private String remark;
  50 +
  51 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  52 + private String fileUrl;
  53 +
  54 + @Schema(description = "审核人", example = "芋道")
  55 + private String creator;
  56 + @Schema(description = "审核人名称", example = "芋道")
  57 + private String creatorName;
  58 +
  59 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  60 + @ExcelProperty("创建时间")
  61 + private LocalDateTime createTime;
  62 +
  63 + @Schema(description = "盘点项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  64 + private List<Item> items;
  65 +
  66 + @Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED)
  67 + @ExcelProperty("产品信息")
  68 + private String productNames;
  69 +
  70 + @Data
  71 + public static class Item {
  72 +
  73 + @Schema(description = "盘点项编号", example = "11756")
  74 + private Long id;
  75 +
  76 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  77 + private Long warehouseId;
  78 +
  79 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  80 + private Long productId;
  81 +
  82 + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  83 + private BigDecimal productPrice;
  84 +
  85 + @Schema(description = "账面数量(当前库存)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  86 + @NotNull(message = "账面数量不能为空")
  87 + private BigDecimal stockCount;
  88 +
  89 + @Schema(description = "实际数量(实际库存)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  90 + @NotNull(message = "实际数量不能为空")
  91 + private BigDecimal actualCount;
  92 +
  93 + @Schema(description = "盈亏数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  94 + @NotNull(message = "盈亏数量不能为空")
  95 + private BigDecimal count;
  96 +
  97 + @Schema(description = "备注", example = "随便")
  98 + private String remark;
  99 +
  100 + // ========== 关联字段 ==========
  101 +
  102 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "巧克力")
  103 + private String productName;
  104 + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
  105 + private String productBarCode;
  106 + @Schema(description = "产品单位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "盒")
  107 + private String productUnitName;
  108 +
  109 + }
  110 +
  111 +}
0 112 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDateTime;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - ERP 其它出库单新增/修改 Request VO")
  14 +@Data
  15 +public class ErpStockCheckSaveReqVO {
  16 +
  17 + @Schema(description = "出库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  18 + private Long id;
  19 +
  20 + @Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED)
  21 + @NotNull(message = "出库时间不能为空")
  22 + private LocalDateTime checkTime;
  23 +
  24 + @Schema(description = "备注", example = "随便")
  25 + private String remark;
  26 +
  27 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  28 + private String fileUrl;
  29 +
  30 + @Schema(description = "出库项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + @NotEmpty(message = "出库项列表不能为空")
  32 + @Valid
  33 + private List<Item> items;
  34 +
  35 + @Data
  36 + public static class Item {
  37 +
  38 + @Schema(description = "出库项编号", example = "11756")
  39 + private Long id;
  40 +
  41 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  42 + @NotNull(message = "仓库编号不能为空")
  43 + private Long warehouseId;
  44 +
  45 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  46 + @NotNull(message = "产品编号不能为空")
  47 + private Long productId;
  48 +
  49 + @Schema(description = "产品单价", example = "100.00")
  50 + private BigDecimal productPrice;
  51 +
  52 + @Schema(description = "账面数量(当前库存)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  53 + @NotNull(message = "账面数量不能为空")
  54 + private BigDecimal stockCount;
  55 +
  56 + @Schema(description = "实际数量(实际库存)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  57 + @NotNull(message = "实际数量不能为空")
  58 + private BigDecimal actualCount;
  59 +
  60 + @Schema(description = "盈亏数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  61 + @NotNull(message = "盈亏数量不能为空")
  62 + private BigDecimal count;
  63 +
  64 + @Schema(description = "备注", example = "随便")
  65 + private String remark;
  66 +
  67 + }
  68 +
  69 +}
0 70 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +import org.springframework.format.annotation.DateTimeFormat;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@Schema(description = "管理后台 - ERP 其它入库单分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class ErpStockInPageReqVO extends PageParam {
  21 +
  22 + @Schema(description = "入库单号", example = "S123")
  23 + private String no;
  24 +
  25 + @Schema(description = "供应商编号", example = "3113")
  26 + private Long supplierId;
  27 +
  28 + @Schema(description = "入库时间")
  29 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  30 + private LocalDateTime[] inTime;
  31 +
  32 + @Schema(description = "状态", example = "10")
  33 + @InEnum(ErpAuditStatus.class)
  34 + private Integer status;
  35 +
  36 + @Schema(description = "备注", example = "随便")
  37 + private String remark;
  38 +
  39 + @Schema(description = "创建者")
  40 + private String creator;
  41 +
  42 + @Schema(description = "产品编号", example = "1")
  43 + private Long productId;
  44 +
  45 + @Schema(description = "仓库编号", example = "1")
  46 + private Long warehouseId;
  47 +
  48 +}
0 49 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import lombok.Data;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.time.LocalDateTime;
  12 +import java.util.List;
  13 +
  14 +import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.AUDIT_STATUS;
  15 +
  16 +@Schema(description = "管理后台 - ERP 其它入库单 Response VO")
  17 +@Data
  18 +@ExcelIgnoreUnannotated
  19 +public class ErpStockInRespVO {
  20 +
  21 + @Schema(description = "入库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  22 + @ExcelProperty("入库编号")
  23 + private Long id;
  24 +
  25 + @Schema(description = "入库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "S123")
  26 + @ExcelProperty("入库单号")
  27 + private String no;
  28 +
  29 + @Schema(description = "供应商编号", example = "3113")
  30 + private Long supplierId;
  31 + @Schema(description = "供应商名称", example = "芋道")
  32 + @ExcelProperty("供应商名称")
  33 + private String supplierName;
  34 +
  35 + @Schema(description = "入库时间", requiredMode = Schema.RequiredMode.REQUIRED)
  36 + @ExcelProperty("入库时间")
  37 + private LocalDateTime inTime;
  38 +
  39 + @Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
  40 + @ExcelProperty("合计数量")
  41 + private BigDecimal totalCount;
  42 +
  43 + @Schema(description = "合计金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
  44 + @ExcelProperty("合计金额")
  45 + private BigDecimal totalPrice;
  46 +
  47 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  48 + @ExcelProperty(value = "状态", converter = DictConvert.class)
  49 + @DictFormat(AUDIT_STATUS)
  50 + private Integer status;
  51 +
  52 + @Schema(description = "备注", example = "随便")
  53 + @ExcelProperty("备注")
  54 + private String remark;
  55 +
  56 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  57 + private String fileUrl;
  58 +
  59 + @Schema(description = "审核人", example = "芋道")
  60 + private String creator;
  61 + @Schema(description = "审核人名称", example = "芋道")
  62 + private String creatorName;
  63 +
  64 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  65 + @ExcelProperty("创建时间")
  66 + private LocalDateTime createTime;
  67 +
  68 + @Schema(description = "入库项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  69 + private List<Item> items;
  70 +
  71 + @Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED)
  72 + @ExcelProperty("产品信息")
  73 + private String productNames;
  74 +
  75 + @Data
  76 + public static class Item {
  77 +
  78 + @Schema(description = "入库项编号", example = "11756")
  79 + private Long id;
  80 +
  81 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  82 + private Long warehouseId;
  83 +
  84 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  85 + private Long productId;
  86 +
  87 + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  88 + private BigDecimal productPrice;
  89 +
  90 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  91 + private BigDecimal count;
  92 +
  93 + @Schema(description = "备注", example = "随便")
  94 + private String remark;
  95 +
  96 + // ========== 关联字段 ==========
  97 +
  98 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "巧克力")
  99 + private String productName;
  100 + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
  101 + private String productBarCode;
  102 + @Schema(description = "产品单位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "盒")
  103 + private String productUnitName;
  104 +
  105 + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  106 + private BigDecimal stockCount; // 该字段仅仅在“详情”和“编辑”时使用
  107 +
  108 + }
  109 +
  110 +}
0 111 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDateTime;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - ERP 其它入库单新增/修改 Request VO")
  14 +@Data
  15 +public class ErpStockInSaveReqVO {
  16 +
  17 + @Schema(description = "入库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  18 + private Long id;
  19 +
  20 + @Schema(description = "供应商编号", example = "3113")
  21 + private Long supplierId;
  22 +
  23 + @Schema(description = "入库时间", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @NotNull(message = "入库时间不能为空")
  25 + private LocalDateTime inTime;
  26 +
  27 + @Schema(description = "备注", example = "随便")
  28 + private String remark;
  29 +
  30 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  31 + private String fileUrl;
  32 +
  33 + @Schema(description = "入库项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + @NotEmpty(message = "入库项列表不能为空")
  35 + @Valid
  36 + private List<Item> items;
  37 +
  38 + @Data
  39 + public static class Item {
  40 +
  41 + @Schema(description = "入库项编号", example = "11756")
  42 + private Long id;
  43 +
  44 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  45 + @NotNull(message = "仓库编号不能为空")
  46 + private Long warehouseId;
  47 +
  48 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  49 + @NotNull(message = "产品编号不能为空")
  50 + private Long productId;
  51 +
  52 + @Schema(description = "产品单价", example = "100.00")
  53 + private BigDecimal productPrice;
  54 +
  55 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  56 + @NotNull(message = "产品数量不能为空")
  57 + private BigDecimal count;
  58 +
  59 + @Schema(description = "备注", example = "随便")
  60 + private String remark;
  61 +
  62 + }
  63 +
  64 +}
0 65 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMovePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +import org.springframework.format.annotation.DateTimeFormat;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@Schema(description = "管理后台 - ERP 库存调拨单分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class ErpStockMovePageReqVO extends PageParam {
  21 +
  22 + @Schema(description = "调拨单号", example = "S123")
  23 + private String no;
  24 +
  25 + @Schema(description = "调拨时间")
  26 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  27 + private LocalDateTime[] moveTime;
  28 +
  29 + @Schema(description = "状态", example = "10")
  30 + @InEnum(ErpAuditStatus.class)
  31 + private Integer status;
  32 +
  33 + @Schema(description = "备注", example = "随便")
  34 + private String remark;
  35 +
  36 + @Schema(description = "创建者")
  37 + private String creator;
  38 +
  39 + @Schema(description = "产品编号", example = "1")
  40 + private Long productId;
  41 +
  42 + @Schema(description = "调出仓库编号", example = "1")
  43 + private Long fromWarehouseId;
  44 +
  45 +}
0 46 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import lombok.Data;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.time.LocalDateTime;
  12 +import java.util.List;
  13 +
  14 +import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.AUDIT_STATUS;
  15 +
  16 +@Schema(description = "管理后台 - ERP 库存调拨单 Response VO")
  17 +@Data
  18 +@ExcelIgnoreUnannotated
  19 +public class ErpStockMoveRespVO {
  20 +
  21 + @Schema(description = "调拨编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  22 + @ExcelProperty("调拨编号")
  23 + private Long id;
  24 +
  25 + @Schema(description = "调拨单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "S123")
  26 + @ExcelProperty("调拨单号")
  27 + private String no;
  28 +
  29 + @Schema(description = "调拨时间", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + @ExcelProperty("调拨时间")
  31 + private LocalDateTime moveTime;
  32 +
  33 + @Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
  34 + @ExcelProperty("合计数量")
  35 + private BigDecimal totalCount;
  36 +
  37 + @Schema(description = "合计金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
  38 + @ExcelProperty("合计金额")
  39 + private BigDecimal totalPrice;
  40 +
  41 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  42 + @ExcelProperty(value = "状态", converter = DictConvert.class)
  43 + @DictFormat(AUDIT_STATUS)
  44 + private Integer status;
  45 +
  46 + @Schema(description = "备注", example = "随便")
  47 + @ExcelProperty("备注")
  48 + private String remark;
  49 +
  50 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  51 + private String fileUrl;
  52 +
  53 + @Schema(description = "审核人", example = "芋道")
  54 + private String creator;
  55 + @Schema(description = "审核人名称", example = "芋道")
  56 + private String creatorName;
  57 +
  58 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  59 + @ExcelProperty("创建时间")
  60 + private LocalDateTime createTime;
  61 +
  62 + @Schema(description = "调拨项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  63 + private List<Item> items;
  64 +
  65 + @Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED)
  66 + @ExcelProperty("产品信息")
  67 + private String productNames;
  68 +
  69 + @Data
  70 + public static class Item {
  71 +
  72 + @Schema(description = "调拨项编号", example = "11756")
  73 + private Long id;
  74 +
  75 + @Schema(description = "调出仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  76 + private Long fromWarehouseId;
  77 +
  78 + @Schema(description = "调入仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
  79 + private Long toWarehouseId;
  80 +
  81 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  82 + private Long productId;
  83 +
  84 + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  85 + private BigDecimal productPrice;
  86 +
  87 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  88 + private BigDecimal count;
  89 +
  90 + @Schema(description = "备注", example = "随便")
  91 + private String remark;
  92 +
  93 + // ========== 关联字段 ==========
  94 +
  95 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "巧克力")
  96 + private String productName;
  97 + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
  98 + private String productBarCode;
  99 + @Schema(description = "产品单位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "盒")
  100 + private String productUnitName;
  101 +
  102 + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  103 + private BigDecimal stockCount; // 该字段仅仅在“详情”和“编辑”时使用
  104 +
  105 + }
  106 +
  107 +}
0 108 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move;
  2 +
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import com.fasterxml.jackson.annotation.JsonIgnore;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.Valid;
  7 +import jakarta.validation.constraints.AssertTrue;
  8 +import jakarta.validation.constraints.NotEmpty;
  9 +import jakarta.validation.constraints.NotNull;
  10 +import lombok.Data;
  11 +
  12 +import java.math.BigDecimal;
  13 +import java.time.LocalDateTime;
  14 +import java.util.List;
  15 +
  16 +@Schema(description = "管理后台 - ERP 库存调拨单新增/修改 Request VO")
  17 +@Data
  18 +public class ErpStockMoveSaveReqVO {
  19 +
  20 + @Schema(description = "调拨编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  21 + private Long id;
  22 +
  23 + @Schema(description = "客户编号", example = "3113")
  24 + private Long customerId;
  25 +
  26 + @Schema(description = "调拨时间", requiredMode = Schema.RequiredMode.REQUIRED)
  27 + @NotNull(message = "调拨时间不能为空")
  28 + private LocalDateTime moveTime;
  29 +
  30 + @Schema(description = "备注", example = "随便")
  31 + private String remark;
  32 +
  33 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  34 + private String fileUrl;
  35 +
  36 + @Schema(description = "调拨项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + @NotEmpty(message = "调拨项列表不能为空")
  38 + @Valid
  39 + private List<Item> items;
  40 +
  41 + @Data
  42 + public static class Item {
  43 +
  44 + @Schema(description = "调拨项编号", example = "11756")
  45 + private Long id;
  46 +
  47 + @Schema(description = "调出仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  48 + @NotNull(message = "调出仓库编号不能为空")
  49 + private Long fromWarehouseId;
  50 +
  51 + @Schema(description = "调入仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
  52 + @NotNull(message = "调入仓库编号不能为空")
  53 + private Long toWarehouseId;
  54 +
  55 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  56 + @NotNull(message = "产品编号不能为空")
  57 + private Long productId;
  58 +
  59 + @Schema(description = "产品单价", example = "100.00")
  60 + private BigDecimal productPrice;
  61 +
  62 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  63 + @NotNull(message = "产品数量不能为空")
  64 + private BigDecimal count;
  65 +
  66 + @Schema(description = "备注", example = "随便")
  67 + private String remark;
  68 +
  69 + @AssertTrue(message = "调出、调仓仓库不能相同")
  70 + @JsonIgnore
  71 + public boolean isWarehouseValid() {
  72 + return ObjectUtil.notEqual(fromWarehouseId, toWarehouseId);
  73 + }
  74 +
  75 + }
  76 +
  77 +}
0 78 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +import org.springframework.format.annotation.DateTimeFormat;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@Schema(description = "管理后台 - ERP 其它出库单分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class ErpStockOutPageReqVO extends PageParam {
  21 +
  22 + @Schema(description = "出库单号", example = "S123")
  23 + private String no;
  24 +
  25 + @Schema(description = "客户编号", example = "3113")
  26 + private Long customerId;
  27 +
  28 + @Schema(description = "出库时间")
  29 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  30 + private LocalDateTime[] outTime;
  31 +
  32 + @Schema(description = "状态", example = "10")
  33 + @InEnum(ErpAuditStatus.class)
  34 + private Integer status;
  35 +
  36 + @Schema(description = "备注", example = "随便")
  37 + private String remark;
  38 +
  39 + @Schema(description = "创建者")
  40 + private String creator;
  41 +
  42 + @Schema(description = "产品编号", example = "1")
  43 + private Long productId;
  44 +
  45 + @Schema(description = "仓库编号", example = "1")
  46 + private Long warehouseId;
  47 +
  48 +}
0 49 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import lombok.Data;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.time.LocalDateTime;
  12 +import java.util.List;
  13 +
  14 +import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.AUDIT_STATUS;
  15 +
  16 +@Schema(description = "管理后台 - ERP 其它出库单 Response VO")
  17 +@Data
  18 +@ExcelIgnoreUnannotated
  19 +public class ErpStockOutRespVO {
  20 +
  21 + @Schema(description = "出库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  22 + @ExcelProperty("出库编号")
  23 + private Long id;
  24 +
  25 + @Schema(description = "出库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "S123")
  26 + @ExcelProperty("出库单号")
  27 + private String no;
  28 +
  29 + @Schema(description = "客户编号", example = "3113")
  30 + private Long customerId;
  31 + @Schema(description = "客户名称", example = "芋道")
  32 + @ExcelProperty("客户名称")
  33 + private String customerName;
  34 +
  35 + @Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED)
  36 + @ExcelProperty("出库时间")
  37 + private LocalDateTime outTime;
  38 +
  39 + @Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
  40 + @ExcelProperty("合计数量")
  41 + private BigDecimal totalCount;
  42 +
  43 + @Schema(description = "合计金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
  44 + @ExcelProperty("合计金额")
  45 + private BigDecimal totalPrice;
  46 +
  47 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  48 + @ExcelProperty(value = "状态", converter = DictConvert.class)
  49 + @DictFormat(AUDIT_STATUS)
  50 + private Integer status;
  51 +
  52 + @Schema(description = "备注", example = "随便")
  53 + @ExcelProperty("备注")
  54 + private String remark;
  55 +
  56 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  57 + private String fileUrl;
  58 +
  59 + @Schema(description = "审核人", example = "芋道")
  60 + private String creator;
  61 + @Schema(description = "审核人名称", example = "芋道")
  62 + private String creatorName;
  63 +
  64 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  65 + @ExcelProperty("创建时间")
  66 + private LocalDateTime createTime;
  67 +
  68 + @Schema(description = "出库项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  69 + private List<Item> items;
  70 +
  71 + @Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED)
  72 + @ExcelProperty("产品信息")
  73 + private String productNames;
  74 +
  75 + @Data
  76 + public static class Item {
  77 +
  78 + @Schema(description = "出库项编号", example = "11756")
  79 + private Long id;
  80 +
  81 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  82 + private Long warehouseId;
  83 +
  84 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  85 + private Long productId;
  86 +
  87 + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  88 + private BigDecimal productPrice;
  89 +
  90 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  91 + private BigDecimal count;
  92 +
  93 + @Schema(description = "备注", example = "随便")
  94 + private String remark;
  95 +
  96 + // ========== 关联字段 ==========
  97 +
  98 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "巧克力")
  99 + private String productName;
  100 + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
  101 + private String productBarCode;
  102 + @Schema(description = "产品单位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "盒")
  103 + private String productUnitName;
  104 +
  105 + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  106 + private BigDecimal stockCount; // 该字段仅仅在“详情”和“编辑”时使用
  107 +
  108 + }
  109 +
  110 +}
0 111 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDateTime;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - ERP 其它出库单新增/修改 Request VO")
  14 +@Data
  15 +public class ErpStockOutSaveReqVO {
  16 +
  17 + @Schema(description = "出库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
  18 + private Long id;
  19 +
  20 + @Schema(description = "客户编号", example = "3113")
  21 + private Long customerId;
  22 +
  23 + @Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @NotNull(message = "出库时间不能为空")
  25 + private LocalDateTime outTime;
  26 +
  27 + @Schema(description = "备注", example = "随便")
  28 + private String remark;
  29 +
  30 + @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
  31 + private String fileUrl;
  32 +
  33 + @Schema(description = "出库项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + @NotEmpty(message = "出库项列表不能为空")
  35 + @Valid
  36 + private List<Item> items;
  37 +
  38 + @Data
  39 + public static class Item {
  40 +
  41 + @Schema(description = "出库项编号", example = "11756")
  42 + private Long id;
  43 +
  44 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  45 + @NotNull(message = "仓库编号不能为空")
  46 + private Long warehouseId;
  47 +
  48 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  49 + @NotNull(message = "产品编号不能为空")
  50 + private Long productId;
  51 +
  52 + @Schema(description = "产品单价", example = "100.00")
  53 + private BigDecimal productPrice;
  54 +
  55 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  56 + @NotNull(message = "产品数量不能为空")
  57 + private BigDecimal count;
  58 +
  59 + @Schema(description = "备注", example = "随便")
  60 + private String remark;
  61 +
  62 + }
  63 +
  64 +}
0 65 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/record/ErpStockRecordPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - ERP 产品库存明细分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class ErpStockRecordPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "产品编号", example = "10625")
  21 + private Long productId;
  22 +
  23 + @Schema(description = "仓库编号", example = "32407")
  24 + private Long warehouseId;
  25 +
  26 + @Schema(description = "业务类型", example = "10")
  27 + private Integer bizType;
  28 +
  29 + @Schema(description = "业务单号", example = "Z110")
  30 + private String bizNo;
  31 +
  32 + @Schema(description = "创建时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] createTime;
  35 +
  36 +}
0 37 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/record/ErpStockRecordRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.erp.enums.DictTypeConstants;
  6 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  7 +import com.alibaba.excel.annotation.ExcelProperty;
  8 +import io.swagger.v3.oas.annotations.media.Schema;
  9 +import lombok.Data;
  10 +
  11 +import java.math.BigDecimal;
  12 +import java.time.LocalDateTime;
  13 +
  14 +@Schema(description = "管理后台 - ERP 产品库存明细 Response VO")
  15 +@Data
  16 +@ExcelIgnoreUnannotated
  17 +public class ErpStockRecordRespVO {
  18 +
  19 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18909")
  20 + @ExcelProperty("编号")
  21 + private Long id;
  22 +
  23 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10625")
  24 + private Long productId;
  25 +
  26 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32407")
  27 + private Long warehouseId;
  28 +
  29 + @Schema(description = "出入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "11084")
  30 + @ExcelProperty("出入库数量")
  31 + private BigDecimal count;
  32 +
  33 + @Schema(description = "总库存量", requiredMode = Schema.RequiredMode.REQUIRED, example = "4307")
  34 + @ExcelProperty("总库存量")
  35 + private BigDecimal totalCount;
  36 +
  37 + @Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  38 + @ExcelProperty(value = "业务类型", converter = DictConvert.class)
  39 + @DictFormat(DictTypeConstants.STOCK_RECORD_BIZ_TYPE)
  40 + private Integer bizType;
  41 +
  42 + @Schema(description = "业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "27093")
  43 + @ExcelProperty("业务编号")
  44 + private Long bizId;
  45 +
  46 + @Schema(description = "业务项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23516")
  47 + @ExcelProperty("业务项编号")
  48 + private Long bizItemId;
  49 +
  50 + @Schema(description = "业务单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "Z110")
  51 + @ExcelProperty("业务单号")
  52 + private String bizNo;
  53 +
  54 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  55 + @ExcelProperty("创建时间")
  56 + private LocalDateTime createTime;
  57 +
  58 + @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "25682")
  59 + private String creator;
  60 +
  61 + // ========== 产品信息 ==========
  62 +
  63 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "苹果")
  64 + @ExcelProperty("产品名称")
  65 + private String productName;
  66 +
  67 + @Schema(description = "产品分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "水果")
  68 + @ExcelProperty("产品分类")
  69 + private String categoryName;
  70 +
  71 + @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "个")
  72 + @ExcelProperty("单位")
  73 + private String unitName;
  74 +
  75 + // ========== 仓库信息 ==========
  76 +
  77 + @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  78 + @ExcelProperty("仓库名称")
  79 + private String warehouseName;
  80 +
  81 + // ========== 用户信息 ==========
  82 +
  83 + @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  84 + @ExcelProperty("创建人")
  85 + private String creatorName;
  86 +
  87 +}
0 88 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - ERP 库存分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class ErpStockPageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "产品编号", example = "19614")
  16 + private Long productId;
  17 +
  18 + @Schema(description = "仓库编号", example = "2802")
  19 + private Long warehouseId;
  20 +
  21 +}
0 22 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock;
  2 +
  3 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  4 +import com.alibaba.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.math.BigDecimal;
  9 +
  10 +@Schema(description = "管理后台 - ERP 库存 Response VO")
  11 +@Data
  12 +@ExcelIgnoreUnannotated
  13 +public class ErpStockRespVO {
  14 +
  15 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17086")
  16 + @ExcelProperty("编号")
  17 + private Long id;
  18 +
  19 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19614")
  20 + private Long productId;
  21 +
  22 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2802")
  23 + private Long warehouseId;
  24 +
  25 + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "21935")
  26 + @ExcelProperty("库存数量")
  27 + private BigDecimal count;
  28 +
  29 + // ========== 产品信息 ==========
  30 +
  31 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "苹果")
  32 + @ExcelProperty("产品名称")
  33 + private String productName;
  34 +
  35 + @Schema(description = "产品分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "水果")
  36 + @ExcelProperty("产品分类")
  37 + private String categoryName;
  38 +
  39 + @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "个")
  40 + @ExcelProperty("单位")
  41 + private String unitName;
  42 +
  43 + // ========== 仓库信息 ==========
  44 +
  45 + @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  46 + @ExcelProperty("仓库名称")
  47 + private String warehouseName;
  48 +
  49 +}
0 50 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/warehouse/ErpWarehousePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +
  11 +@Schema(description = "管理后台 - ERP 仓库分页 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class ErpWarehousePageReqVO extends PageParam {
  16 +
  17 + @Schema(description = "仓库名称", example = "李四")
  18 + private String name;
  19 +
  20 + @Schema(description = "开启状态", example = "1")
  21 + @InEnum(CommonStatusEnum.class)
  22 + private Integer status;
  23 +
  24 +}
0 25 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/warehouse/ErpWarehouseRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
  6 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  7 +import com.alibaba.excel.annotation.ExcelProperty;
  8 +import io.swagger.v3.oas.annotations.media.Schema;
  9 +import lombok.Data;
  10 +
  11 +import java.math.BigDecimal;
  12 +import java.time.LocalDateTime;
  13 +
  14 +@Schema(description = "管理后台 - ERP 仓库 Response VO")
  15 +@Data
  16 +@ExcelIgnoreUnannotated
  17 +public class ErpWarehouseRespVO {
  18 +
  19 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11614")
  20 + @ExcelProperty("仓库编号")
  21 + private Long id;
  22 +
  23 + @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  24 + @ExcelProperty("仓库名称")
  25 + private String name;
  26 +
  27 + @Schema(description = "仓库地址", example = "上海陆家嘴")
  28 + @ExcelProperty("仓库地址")
  29 + private String address;
  30 +
  31 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  32 + @ExcelProperty("排序")
  33 + private Long sort;
  34 +
  35 + @Schema(description = "备注", example = "随便")
  36 + @ExcelProperty("备注")
  37 + private String remark;
  38 +
  39 + @Schema(description = "负责人", example = "芋头")
  40 + @ExcelProperty("负责人")
  41 + private String principal;
  42 +
  43 + @Schema(description = "仓储费,单位:元", example = "13973")
  44 + @ExcelProperty("仓储费,单位:元")
  45 + private BigDecimal warehousePrice;
  46 +
  47 + @Schema(description = "搬运费,单位:元", example = "9903")
  48 + @ExcelProperty("搬运费,单位:元")
  49 + private BigDecimal truckagePrice;
  50 +
  51 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  52 + @ExcelProperty(value = "开启状态", converter = DictConvert.class)
  53 + @DictFormat(DictTypeConstants.COMMON_STATUS)
  54 + private Integer status;
  55 +
  56 + @Schema(description = "是否默认", example = "1")
  57 + @ExcelProperty("是否默认")
  58 + private Boolean defaultStatus;
  59 +
  60 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  61 + @ExcelProperty("创建时间")
  62 + private LocalDateTime createTime;
  63 +
  64 +}
0 65 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/warehouse/ErpWarehouseSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotEmpty;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import lombok.Data;
  9 +
  10 +import java.math.BigDecimal;
  11 +
  12 +@Schema(description = "管理后台 - ERP 仓库新增/修改 Request VO")
  13 +@Data
  14 +public class ErpWarehouseSaveReqVO {
  15 +
  16 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11614")
  17 + private Long id;
  18 +
  19 + @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  20 + @NotEmpty(message = "仓库名称不能为空")
  21 + private String name;
  22 +
  23 + @Schema(description = "仓库地址", example = "上海陆家嘴")
  24 + private String address;
  25 +
  26 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  27 + @NotNull(message = "排序不能为空")
  28 + private Long sort;
  29 +
  30 + @Schema(description = "备注", example = "随便")
  31 + private String remark;
  32 +
  33 + @Schema(description = "负责人", example = "芋头")
  34 + private String principal;
  35 +
  36 + @Schema(description = "仓储费,单位:元", example = "13973")
  37 + private BigDecimal warehousePrice;
  38 +
  39 + @Schema(description = "搬运费,单位:元", example = "9903")
  40 + private BigDecimal truckagePrice;
  41 +
  42 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  43 + @NotNull(message = "开启状态不能为空")
  44 + @InEnum(CommonStatusEnum.class)
  45 + private Integer status;
  46 +
  47 +}
0 48 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/product/ErpProductDO.java
... ... @@ -45,9 +45,9 @@ public class ErpProductDO extends BaseDO {
45 45 /**
46 46 * 单位编号
47 47 *
48   - * TODO 芋艿,关联
  48 + * 关联 {@link ErpProductUnitDO#getId()}
49 49 */
50   - private Integer unitId;
  50 + private Long unitId;
51 51 /**
52 52 * 产品状态
53 53 *
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpSupplierDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +
  11 +/**
  12 + * ERP 供应商 DO
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@TableName("erp_supplier")
  17 +@KeySequence("erp_supplier_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class ErpSupplierDO extends BaseDO {
  25 +
  26 + /**
  27 + * 供应商编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + /**
  32 + * 供应商名称
  33 + */
  34 + private String name;
  35 + /**
  36 + * 联系人
  37 + */
  38 + private String contact;
  39 + /**
  40 + * 手机号码
  41 + */
  42 + private String mobile;
  43 + /**
  44 + * 联系电话
  45 + */
  46 + private String telephone;
  47 + /**
  48 + * 电子邮箱
  49 + */
  50 + private String email;
  51 + /**
  52 + * 传真
  53 + */
  54 + private String fax;
  55 + /**
  56 + * 备注
  57 + */
  58 + private String remark;
  59 + /**
  60 + * 开启状态
  61 + *
  62 + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  63 + */
  64 + private Integer status;
  65 + /**
  66 + * 排序
  67 + */
  68 + private Integer sort;
  69 + /**
  70 + * 纳税人识别号
  71 + */
  72 + private String taxNo;
  73 + /**
  74 + * 税率
  75 + */
  76 + private BigDecimal taxPercent;
  77 + /**
  78 + * 开户行
  79 + */
  80 + private String bankName;
  81 + /**
  82 + * 开户账号
  83 + */
  84 + private String bankAccount;
  85 + /**
  86 + * 开户地址
  87 + */
  88 + private String bankAddress;
  89 +
  90 +}
0 91 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpCustomerDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.sale;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +
  11 +/**
  12 + * ERP 客户 DO
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@TableName("erp_customer")
  17 +@KeySequence("erp_customer_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class ErpCustomerDO extends BaseDO {
  25 +
  26 + /**
  27 + * 客户编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + /**
  32 + * 客户名称
  33 + */
  34 + private String name;
  35 + /**
  36 + * 联系人
  37 + */
  38 + private String contact;
  39 + /**
  40 + * 手机号码
  41 + */
  42 + private String mobile;
  43 + /**
  44 + * 联系电话
  45 + */
  46 + private String telephone;
  47 + /**
  48 + * 电子邮箱
  49 + */
  50 + private String email;
  51 + /**
  52 + * 传真
  53 + */
  54 + private String fax;
  55 + /**
  56 + * 备注
  57 + */
  58 + private String remark;
  59 + /**
  60 + * 开启状态
  61 + *
  62 + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  63 + */
  64 + private Integer status;
  65 + /**
  66 + * 排序
  67 + */
  68 + private Integer sort;
  69 + /**
  70 + * 纳税人识别号
  71 + */
  72 + private String taxNo;
  73 + /**
  74 + * 税率
  75 + */
  76 + private BigDecimal taxPercent;
  77 + /**
  78 + * 开户行
  79 + */
  80 + private String bankName;
  81 + /**
  82 + * 开户账号
  83 + */
  84 + private String bankAccount;
  85 + /**
  86 + * 开户地址
  87 + */
  88 + private String bankAddress;
  89 +
  90 +}
0 91 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockCheckDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDateTime;
  11 +
  12 +/**
  13 + * ERP 库存盘点单 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock_check")
  18 +@KeySequence("erp_stock_check_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockCheckDO extends BaseDO {
  26 +
  27 + /**
  28 + * 盘点编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 盘点单号
  34 + */
  35 + private String no;
  36 + /**
  37 + * 盘点时间
  38 + */
  39 + private LocalDateTime checkTime;
  40 + /**
  41 + * 合计数量
  42 + */
  43 + private BigDecimal totalCount;
  44 + /**
  45 + * 合计金额,单位:元
  46 + */
  47 + private BigDecimal totalPrice;
  48 + /**
  49 + * 状态
  50 + *
  51 + * 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
  52 + */
  53 + private Integer status;
  54 + /**
  55 + * 备注
  56 + */
  57 + private String remark;
  58 + /**
  59 + * 附件 URL
  60 + */
  61 + private String fileUrl;
  62 +
  63 +}
0 64 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockCheckItemDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +
  12 +/**
  13 + * ERP 库存盘点单项 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock_check_item")
  18 +@KeySequence("erp_stock_check_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockCheckItemDO extends BaseDO {
  26 +
  27 + /**
  28 + * 盘点项编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 盘点编号
  34 + *
  35 + * 关联 {@link ErpStockCheckDO#getId()}
  36 + */
  37 + private Long checkId;
  38 + /**
  39 + * 仓库编号
  40 + *
  41 + * 关联 {@link ErpWarehouseDO#getId()}
  42 + */
  43 + private Long warehouseId;
  44 + /**
  45 + * 产品编号
  46 + *
  47 + * 关联 {@link ErpProductDO#getId()}
  48 + */
  49 + private Long productId;
  50 + /**
  51 + * 产品单位编号
  52 + *
  53 + * 冗余 {@link ErpProductDO#getUnitId()}
  54 + */
  55 + private Long productUnitId;
  56 + /**
  57 + * 产品单价
  58 + */
  59 + private BigDecimal productPrice;
  60 + /**
  61 + * 账面数量(当前库存)
  62 + */
  63 + private BigDecimal stockCount;
  64 + /**
  65 + * 实际数量(实际库存)
  66 + */
  67 + private BigDecimal actualCount;
  68 + /**
  69 + * 盈亏数量
  70 + *
  71 + * count = stockCount - actualCount
  72 + */
  73 + private BigDecimal count;
  74 + /**
  75 + * 合计金额,单位:元
  76 + */
  77 + private BigDecimal totalPrice;
  78 + /**
  79 + * 备注
  80 + */
  81 + private String remark;
  82 +
  83 +}
0 84 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +
  12 +/**
  13 + * ERP 产品库存 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock")
  18 +@KeySequence("erp_stock_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockDO extends BaseDO {
  26 +
  27 + /**
  28 + * 编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 产品编号
  34 + *
  35 + * 关联 {@link ErpProductDO#getId()}
  36 + */
  37 + private Long productId;
  38 + /**
  39 + * 仓库编号
  40 + *
  41 + * 关联 {@link ErpWarehouseDO#getId()}
  42 + */
  43 + private Long warehouseId;
  44 + /**
  45 + * 库存数量
  46 + */
  47 + private BigDecimal count;
  48 +
  49 +}
0 50 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.time.LocalDateTime;
  12 +
  13 +/**
  14 + * ERP 其它入库单 DO
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@TableName("erp_stock_in")
  19 +@KeySequence("erp_stock_in_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  20 +@Data
  21 +@EqualsAndHashCode(callSuper = true)
  22 +@ToString(callSuper = true)
  23 +@Builder
  24 +@NoArgsConstructor
  25 +@AllArgsConstructor
  26 +public class ErpStockInDO extends BaseDO {
  27 +
  28 + /**
  29 + * 入库编号
  30 + */
  31 + @TableId
  32 + private Long id;
  33 + /**
  34 + * 入库单号
  35 + */
  36 + private String no;
  37 + /**
  38 + * 供应商编号
  39 + *
  40 + * 关联 {@link ErpSupplierDO#getId()}
  41 + */
  42 + private Long supplierId;
  43 + /**
  44 + * 入库时间
  45 + */
  46 + private LocalDateTime inTime;
  47 + /**
  48 + * 合计数量
  49 + */
  50 + private BigDecimal totalCount;
  51 + /**
  52 + * 合计金额,单位:元
  53 + */
  54 + private BigDecimal totalPrice;
  55 + /**
  56 + * 状态
  57 + *
  58 + * 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
  59 + */
  60 + private Integer status;
  61 + /**
  62 + * 备注
  63 + */
  64 + private String remark;
  65 + /**
  66 + * 附件 URL
  67 + */
  68 + private String fileUrl;
  69 +
  70 +}
0 71 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +
  12 +/**
  13 + * ERP 其它入库单项 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock_in_item")
  18 +@KeySequence("erp_stock_in_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockInItemDO extends BaseDO {
  26 +
  27 + /**
  28 + * 入库项编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 入库编号
  34 + *
  35 + * 关联 {@link ErpStockInDO#getId()}
  36 + */
  37 + private Long inId;
  38 + /**
  39 + * 仓库编号
  40 + *
  41 + * 关联 {@link ErpWarehouseDO#getId()}
  42 + */
  43 + private Long warehouseId;
  44 + /**
  45 + * 产品编号
  46 + *
  47 + * 关联 {@link ErpProductDO#getId()}
  48 + */
  49 + private Long productId;
  50 + /**
  51 + * 产品单位编号
  52 + *
  53 + * 冗余 {@link ErpProductDO#getUnitId()}
  54 + */
  55 + private Long productUnitId;
  56 + /**
  57 + * 产品单价
  58 + */
  59 + private BigDecimal productPrice;
  60 + /**
  61 + * 产品数量
  62 + */
  63 + private BigDecimal count;
  64 + /**
  65 + * 合计金额,单位:元
  66 + */
  67 + private BigDecimal totalPrice;
  68 + /**
  69 + * 备注
  70 + */
  71 + private String remark;
  72 +
  73 +}
0 74 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDateTime;
  11 +
  12 +/**
  13 + * ERP 库存调拨单 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock_move")
  18 +@KeySequence("erp_stock_move_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockMoveDO extends BaseDO {
  26 +
  27 + /**
  28 + * 调拨编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 调拨单号
  34 + */
  35 + private String no;
  36 + /**
  37 + * 调拨时间
  38 + */
  39 + private LocalDateTime moveTime;
  40 + /**
  41 + * 合计数量
  42 + */
  43 + private BigDecimal totalCount;
  44 + /**
  45 + * 合计金额,单位:元
  46 + */
  47 + private BigDecimal totalPrice;
  48 + /**
  49 + * 状态
  50 + *
  51 + * 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
  52 + */
  53 + private Integer status;
  54 + /**
  55 + * 备注
  56 + */
  57 + private String remark;
  58 + /**
  59 + * 附件 URL
  60 + */
  61 + private String fileUrl;
  62 +
  63 +}
0 64 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveItemDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +
  12 +/**
  13 + * ERP 库存调拨单项 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock_move_item")
  18 +@KeySequence("erp_stock_move_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockMoveItemDO extends BaseDO {
  26 +
  27 + /**
  28 + * 调拨项编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 调拨编号
  34 + *
  35 + * 关联 {@link ErpStockMoveDO#getId()}
  36 + */
  37 + private Long moveId;
  38 + /**
  39 + * 调出仓库编号
  40 + *
  41 + * 关联 {@link ErpWarehouseDO#getId()}
  42 + */
  43 + private Long fromWarehouseId;
  44 + /**
  45 + * 调入仓库编号
  46 + *
  47 + * 关联 {@link ErpWarehouseDO#getId()}
  48 + */
  49 + private Long toWarehouseId;
  50 + /**
  51 + * 产品编号
  52 + *
  53 + * 关联 {@link ErpProductDO#getId()}
  54 + */
  55 + private Long productId;
  56 + /**
  57 + * 产品单位编号
  58 + *
  59 + * 冗余 {@link ErpProductDO#getUnitId()}
  60 + */
  61 + private Long productUnitId;
  62 + /**
  63 + * 产品单价
  64 + */
  65 + private BigDecimal productPrice;
  66 + /**
  67 + * 产品数量
  68 + */
  69 + private BigDecimal count;
  70 + /**
  71 + * 合计金额,单位:元
  72 + */
  73 + private BigDecimal totalPrice;
  74 + /**
  75 + * 备注
  76 + */
  77 + private String remark;
  78 +
  79 +}
0 80 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDateTime;
  11 +
  12 +/**
  13 + * ERP 其它出库单 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock_out")
  18 +@KeySequence("erp_stock_out_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockOutDO extends BaseDO {
  26 +
  27 + /**
  28 + * 出库编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 出库单号
  34 + */
  35 + private String no;
  36 + /**
  37 + * 客户编号
  38 + *
  39 + * TODO 芋艿:待关联
  40 + */
  41 + private Long customerId;
  42 + /**
  43 + * 出库时间
  44 + */
  45 + private LocalDateTime outTime;
  46 + /**
  47 + * 合计数量
  48 + */
  49 + private BigDecimal totalCount;
  50 + /**
  51 + * 合计金额,单位:元
  52 + */
  53 + private BigDecimal totalPrice;
  54 + /**
  55 + * 状态
  56 + *
  57 + * 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
  58 + */
  59 + private Integer status;
  60 + /**
  61 + * 备注
  62 + */
  63 + private String remark;
  64 + /**
  65 + * 附件 URL
  66 + */
  67 + private String fileUrl;
  68 +
  69 +}
0 70 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +
  12 +/**
  13 + * ERP 其它出库单项 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_stock_out_item")
  18 +@KeySequence("erp_stock_out_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpStockOutItemDO extends BaseDO {
  26 +
  27 + /**
  28 + * 出库项编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 出库编号
  34 + *
  35 + * 关联 {@link ErpStockOutDO#getId()}
  36 + */
  37 + private Long outId;
  38 + /**
  39 + * 仓库编号
  40 + *
  41 + * 关联 {@link ErpWarehouseDO#getId()}
  42 + */
  43 + private Long warehouseId;
  44 + /**
  45 + * 产品编号
  46 + *
  47 + * 关联 {@link ErpProductDO#getId()}
  48 + */
  49 + private Long productId;
  50 + /**
  51 + * 产品单位编号
  52 + *
  53 + * 冗余 {@link ErpProductDO#getUnitId()}
  54 + */
  55 + private Long productUnitId;
  56 + /**
  57 + * 产品单价
  58 + */
  59 + private BigDecimal productPrice;
  60 + /**
  61 + * 产品数量
  62 + */
  63 + private BigDecimal count;
  64 + /**
  65 + * 合计金额,单位:元
  66 + */
  67 + private BigDecimal totalPrice;
  68 + /**
  69 + * 备注
  70 + */
  71 + private String remark;
  72 +
  73 +}
0 74 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockRecordDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  5 +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
  6 +import com.baomidou.mybatisplus.annotation.KeySequence;
  7 +import com.baomidou.mybatisplus.annotation.TableId;
  8 +import com.baomidou.mybatisplus.annotation.TableName;
  9 +import lombok.*;
  10 +
  11 +import java.math.BigDecimal;
  12 +
  13 +/**
  14 + * ERP 产品库存明细 DO
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@TableName("erp_stock_record")
  19 +@KeySequence("erp_stock_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  20 +@Data
  21 +@EqualsAndHashCode(callSuper = true)
  22 +@ToString(callSuper = true)
  23 +@Builder
  24 +@NoArgsConstructor
  25 +@AllArgsConstructor
  26 +public class ErpStockRecordDO extends BaseDO {
  27 +
  28 + /**
  29 + * 编号
  30 + */
  31 + @TableId
  32 + private Long id;
  33 + /**
  34 + * 产品编号
  35 + *
  36 + * 关联 {@link ErpProductDO#getId()}
  37 + */
  38 + private Long productId;
  39 + /**
  40 + * 仓库编号
  41 + *
  42 + * 关联 {@link ErpWarehouseDO#getId()}
  43 + */
  44 + private Long warehouseId;
  45 + /**
  46 + * 出入库数量
  47 + *
  48 + * 正数,表示入库;负数,表示出库
  49 + */
  50 + private BigDecimal count;
  51 + /**
  52 + * 总库存量
  53 + *
  54 + * 出入库之后,目前的库存量
  55 + */
  56 + private BigDecimal totalCount;
  57 + /**
  58 + * 业务类型
  59 + *
  60 + * 枚举 {@link ErpStockRecordBizTypeEnum}
  61 + */
  62 + private Integer bizType;
  63 + /**
  64 + * 业务编号
  65 + *
  66 + * 例如说:{@link ErpStockInDO#getId()}
  67 + */
  68 + private Long bizId;
  69 + /**
  70 + * 业务项编号
  71 + *
  72 + * 例如说:{@link ErpStockInItemDO#getId()}
  73 + */
  74 + private Long bizItemId;
  75 + /**
  76 + * 业务单号
  77 + *
  78 + * 例如说:{@link ErpStockInDO#getNo()}
  79 + */
  80 + private String bizNo;
  81 +
  82 +}
0 83 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpWarehouseDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +
  11 +/**
  12 + * ERP 仓库 DO
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@TableName("erp_warehouse")
  17 +@KeySequence("erp_warehouse_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class ErpWarehouseDO extends BaseDO {
  25 +
  26 + /**
  27 + * 仓库编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + /**
  32 + * 仓库名称
  33 + */
  34 + private String name;
  35 + /**
  36 + * 仓库地址
  37 + */
  38 + private String address;
  39 + /**
  40 + * 排序
  41 + */
  42 + private Long sort;
  43 + /**
  44 + * 备注
  45 + */
  46 + private String remark;
  47 + /**
  48 + * 负责人
  49 + */
  50 + private String principal;
  51 + /**
  52 + * 仓储费,单位:元
  53 + */
  54 + private BigDecimal warehousePrice;
  55 + /**
  56 + * 搬运费,单位:元
  57 + */
  58 + private BigDecimal truckagePrice;
  59 + /**
  60 + * 开启状态
  61 + *
  62 + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  63 + */
  64 + private Integer status;
  65 + /**
  66 + * 是否默认
  67 + */
  68 + private Boolean defaultStatus;
  69 +
  70 +}
0 71 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/product/ErpProductMapper.java
... ... @@ -3,10 +3,12 @@ package cn.iocoder.yudao.module.erp.dal.mysql.product;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6   -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPageReqVO;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
7 7 import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
  10 +import java.util.List;
  11 +
10 12 /**
11 13 * ERP 产品 Mapper
12 14 *
... ... @@ -15,7 +17,7 @@ import org.apache.ibatis.annotations.Mapper;
15 17 @Mapper
16 18 public interface ErpProductMapper extends BaseMapperX<ErpProductDO> {
17 19  
18   - default PageResult<ErpProductDO> selectPage(ProductPageReqVO reqVO) {
  20 + default PageResult<ErpProductDO> selectPage(ErpProductPageReqVO reqVO) {
19 21 return selectPage(reqVO, new LambdaQueryWrapperX<ErpProductDO>()
20 22 .likeIfPresent(ErpProductDO::getName, reqVO.getName())
21 23 .eqIfPresent(ErpProductDO::getCategoryId, reqVO.getCategoryId())
... ... @@ -23,4 +25,16 @@ public interface ErpProductMapper extends BaseMapperX&lt;ErpProductDO&gt; {
23 25 .orderByDesc(ErpProductDO::getId));
24 26 }
25 27  
  28 + default Long selectCountByCategoryId(Long categoryId) {
  29 + return selectCount(ErpProductDO::getCategoryId, categoryId);
  30 + }
  31 +
  32 + default Long selectCountByUnitId(Long unitId) {
  33 + return selectCount(ErpProductDO::getUnitId, unitId);
  34 + }
  35 +
  36 + default List<ErpProductDO> selectListByStatus(Integer status) {
  37 + return selectList(ErpProductDO::getStatus, status);
  38 + }
  39 +
26 40 }
27 41 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/product/ErpProductUnitMapper.java
... ... @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUn
7 7 import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
  10 +import java.util.List;
  11 +
10 12 /**
11 13 * ERP 产品单位 Mapper
12 14 *
... ... @@ -19,8 +21,15 @@ public interface ErpProductUnitMapper extends BaseMapperX&lt;ErpProductUnitDO&gt; {
19 21 return selectPage(reqVO, new LambdaQueryWrapperX<ErpProductUnitDO>()
20 22 .likeIfPresent(ErpProductUnitDO::getName, reqVO.getName())
21 23 .eqIfPresent(ErpProductUnitDO::getStatus, reqVO.getStatus())
22   - .betweenIfPresent(ErpProductUnitDO::getCreateTime, reqVO.getCreateTime())
23 24 .orderByDesc(ErpProductUnitDO::getId));
24 25 }
25 26  
  27 + default ErpProductUnitDO selectByName(String name) {
  28 + return selectOne(ErpProductUnitDO::getName, name);
  29 + }
  30 +
  31 + default List<ErpProductUnitDO> selectListByStatus(Integer status) {
  32 + return selectList(ErpProductUnitDO::getStatus, status);
  33 + }
  34 +
26 35 }
27 36 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpSupplierMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * ERP 供应商 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpSupplierMapper extends BaseMapperX<ErpSupplierDO> {
  19 +
  20 + default PageResult<ErpSupplierDO> selectPage(ErpSupplierPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<ErpSupplierDO>()
  22 + .likeIfPresent(ErpSupplierDO::getName, reqVO.getName())
  23 + .likeIfPresent(ErpSupplierDO::getMobile, reqVO.getMobile())
  24 + .likeIfPresent(ErpSupplierDO::getTelephone, reqVO.getTelephone())
  25 + .orderByDesc(ErpSupplierDO::getId));
  26 + }
  27 +
  28 + default List<ErpSupplierDO> selectListByStatus(Integer status) {
  29 + return selectList(ErpSupplierDO::getStatus, status);
  30 + }
  31 +
  32 +}
0 33 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpCustomerMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.sale;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * ERP 客户 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpCustomerMapper extends BaseMapperX<ErpCustomerDO> {
  19 +
  20 + default PageResult<ErpCustomerDO> selectPage(ErpCustomerPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<ErpCustomerDO>()
  22 + .likeIfPresent(ErpCustomerDO::getName, reqVO.getName())
  23 + .eqIfPresent(ErpCustomerDO::getMobile, reqVO.getMobile())
  24 + .eqIfPresent(ErpCustomerDO::getTelephone, reqVO.getTelephone())
  25 + .orderByDesc(ErpCustomerDO::getId));
  26 + }
  27 +
  28 + default List<ErpCustomerDO> selectListByStatus(Integer status) {
  29 + return selectList(ErpCustomerDO::getStatus, status);
  30 + }
  31 +
  32 +}
0 33 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckItemMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * ERP 库存盘点单项 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface ErpStockCheckItemMapper extends BaseMapperX<ErpStockCheckItemDO> {
  17 +
  18 + default List<ErpStockCheckItemDO> selectListByCheckId(Long checkId) {
  19 + return selectList(ErpStockCheckItemDO::getCheckId, checkId);
  20 + }
  21 +
  22 + default List<ErpStockCheckItemDO> selectListByCheckIds(Collection<Long> checkIds) {
  23 + return selectList(ErpStockCheckItemDO::getCheckId, checkIds);
  24 + }
  25 +
  26 + default int deleteByCheckId(Long checkId) {
  27 + return delete(ErpStockCheckItemDO::getCheckId, checkId);
  28 + }
  29 +
  30 +}
0 31 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
  9 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +/**
  13 + * ERP 库存调拨单 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpStockCheckMapper extends BaseMapperX<ErpStockCheckDO> {
  19 +
  20 + default PageResult<ErpStockCheckDO> selectPage(ErpStockCheckPageReqVO reqVO) {
  21 + MPJLambdaWrapperX<ErpStockCheckDO> query = new MPJLambdaWrapperX<ErpStockCheckDO>()
  22 + .eqIfPresent(ErpStockCheckDO::getNo, reqVO.getNo())
  23 + .betweenIfPresent(ErpStockCheckDO::getCheckTime, reqVO.getCheckTime())
  24 + .eqIfPresent(ErpStockCheckDO::getStatus, reqVO.getStatus())
  25 + .likeIfPresent(ErpStockCheckDO::getRemark, reqVO.getRemark())
  26 + .eqIfPresent(ErpStockCheckDO::getCreator, reqVO.getCreator())
  27 + .orderByDesc(ErpStockCheckDO::getId);
  28 + if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
  29 + query.leftJoin(ErpStockCheckItemDO.class, ErpStockCheckItemDO::getCheckId, ErpStockCheckDO::getId)
  30 + .eq(reqVO.getWarehouseId() != null, ErpStockCheckItemDO::getWarehouseId, reqVO.getWarehouseId())
  31 + .eq(reqVO.getProductId() != null, ErpStockCheckItemDO::getProductId, reqVO.getProductId())
  32 + .groupBy(ErpStockCheckDO::getId); // 避免 1 对多查询,产生相同的 1
  33 + }
  34 + return selectJoinPage(reqVO, ErpStockCheckDO.class, query);
  35 + }
  36 +
  37 + default int updateByIdAndStatus(Long id, Integer status, ErpStockCheckDO updateObj) {
  38 + return update(updateObj, new LambdaUpdateWrapper<ErpStockCheckDO>()
  39 + .eq(ErpStockCheckDO::getId, id).eq(ErpStockCheckDO::getStatus, status));
  40 + }
  41 +
  42 + default ErpStockCheckDO selectByNo(String no) {
  43 + return selectOne(ErpStockCheckDO::getNo, no);
  44 + }
  45 +
  46 +}
0 47 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInItemMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * ERP 其它入库单项 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface ErpStockInItemMapper extends BaseMapperX<ErpStockInItemDO> {
  17 +
  18 + default List<ErpStockInItemDO> selectListByInId(Long inId) {
  19 + return selectList(ErpStockInItemDO::getInId, inId);
  20 + }
  21 +
  22 + default List<ErpStockInItemDO> selectListByInIds(Collection<Long> inIds) {
  23 + return selectList(ErpStockInItemDO::getInId, inIds);
  24 + }
  25 +
  26 + default int deleteByInId(Long inId) {
  27 + return delete(ErpStockInItemDO::getInId, inId);
  28 + }
  29 +
  30 +}
0 31 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
  9 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +/**
  13 + * ERP 其它入库单 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpStockInMapper extends BaseMapperX<ErpStockInDO> {
  19 +
  20 + default PageResult<ErpStockInDO> selectPage(ErpStockInPageReqVO reqVO) {
  21 + MPJLambdaWrapperX<ErpStockInDO> query = new MPJLambdaWrapperX<ErpStockInDO>()
  22 + .eqIfPresent(ErpStockInDO::getNo, reqVO.getNo())
  23 + .eqIfPresent(ErpStockInDO::getSupplierId, reqVO.getSupplierId())
  24 + .betweenIfPresent(ErpStockInDO::getInTime, reqVO.getInTime())
  25 + .eqIfPresent(ErpStockInDO::getStatus, reqVO.getStatus())
  26 + .likeIfPresent(ErpStockInDO::getRemark, reqVO.getRemark())
  27 + .eqIfPresent(ErpStockInDO::getCreator, reqVO.getCreator())
  28 + .orderByDesc(ErpStockInDO::getId);
  29 + if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
  30 + query.leftJoin(ErpStockInItemDO.class, ErpStockInItemDO::getInId, ErpStockInDO::getId)
  31 + .eq(reqVO.getWarehouseId() != null, ErpStockInItemDO::getWarehouseId, reqVO.getWarehouseId())
  32 + .eq(reqVO.getProductId() != null, ErpStockInItemDO::getProductId, reqVO.getProductId())
  33 + .groupBy(ErpStockInDO::getId); // 避免 1 对多查询,产生相同的 1
  34 + }
  35 + return selectJoinPage(reqVO, ErpStockInDO.class, query);
  36 + }
  37 +
  38 + default int updateByIdAndStatus(Long id, Integer status, ErpStockInDO updateObj) {
  39 + return update(updateObj, new LambdaUpdateWrapper<ErpStockInDO>()
  40 + .eq(ErpStockInDO::getId, id).eq(ErpStockInDO::getStatus, status));
  41 + }
  42 +
  43 + default ErpStockInDO selectByNo(String no) {
  44 + return selectOne(ErpStockInDO::getNo, no);
  45 + }
  46 +
  47 +}
0 48 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
  8 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.math.BigDecimal;
  12 +
  13 +/**
  14 + * ERP 产品库存 Mapper
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Mapper
  19 +public interface ErpStockMapper extends BaseMapperX<ErpStockDO> {
  20 +
  21 + default PageResult<ErpStockDO> selectPage(ErpStockPageReqVO reqVO) {
  22 + return selectPage(reqVO, new LambdaQueryWrapperX<ErpStockDO>()
  23 + .eqIfPresent(ErpStockDO::getProductId, reqVO.getProductId())
  24 + .eqIfPresent(ErpStockDO::getWarehouseId, reqVO.getWarehouseId())
  25 + .orderByDesc(ErpStockDO::getId));
  26 + }
  27 +
  28 + default ErpStockDO selectByProductIdAndWarehouseId(Long productId, Long warehouseId) {
  29 + return selectOne(ErpStockDO::getProductId, productId,
  30 + ErpStockDO::getWarehouseId, warehouseId);
  31 + }
  32 +
  33 + default int updateCountIncrement(Long id, BigDecimal count, boolean negativeEnable) {
  34 + LambdaUpdateWrapper<ErpStockDO> updateWrapper = new LambdaUpdateWrapper<ErpStockDO>()
  35 + .eq(ErpStockDO::getId, id);
  36 + if (count.compareTo(BigDecimal.ZERO) > 0) {
  37 + updateWrapper.setSql("count = count + " + count);
  38 + } else if (count.compareTo(BigDecimal.ZERO) < 0) {
  39 + if (!negativeEnable) {
  40 + updateWrapper.gt(ErpStockDO::getCount, count.abs());
  41 + }
  42 + updateWrapper.setSql("count = count - " + count.abs());
  43 + }
  44 + return update(null, updateWrapper);
  45 + }
  46 +
  47 +}
0 48 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveItemMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * ERP 库存调拨单项 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface ErpStockMoveItemMapper extends BaseMapperX<ErpStockMoveItemDO> {
  17 +
  18 + default List<ErpStockMoveItemDO> selectListByMoveId(Long moveId) {
  19 + return selectList(ErpStockMoveItemDO::getMoveId, moveId);
  20 + }
  21 +
  22 + default List<ErpStockMoveItemDO> selectListByMoveIds(Collection<Long> moveIds) {
  23 + return selectList(ErpStockMoveItemDO::getMoveId, moveIds);
  24 + }
  25 +
  26 + default int deleteByMoveId(Long moveId) {
  27 + return delete(ErpStockMoveItemDO::getMoveId, moveId);
  28 + }
  29 +
  30 +}
0 31 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO;
  9 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +/**
  13 + * ERP 库存调拨单 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpStockMoveMapper extends BaseMapperX<ErpStockMoveDO> {
  19 +
  20 + default PageResult<ErpStockMoveDO> selectPage(ErpStockMovePageReqVO reqVO) {
  21 + MPJLambdaWrapperX<ErpStockMoveDO> query = new MPJLambdaWrapperX<ErpStockMoveDO>()
  22 + .eqIfPresent(ErpStockMoveDO::getNo, reqVO.getNo())
  23 + .betweenIfPresent(ErpStockMoveDO::getMoveTime, reqVO.getMoveTime())
  24 + .eqIfPresent(ErpStockMoveDO::getStatus, reqVO.getStatus())
  25 + .likeIfPresent(ErpStockMoveDO::getRemark, reqVO.getRemark())
  26 + .eqIfPresent(ErpStockMoveDO::getCreator, reqVO.getCreator())
  27 + .orderByDesc(ErpStockMoveDO::getId);
  28 + if (reqVO.getFromWarehouseId() != null || reqVO.getProductId() != null) {
  29 + query.leftJoin(ErpStockMoveItemDO.class, ErpStockMoveItemDO::getMoveId, ErpStockMoveDO::getId)
  30 + .eq(reqVO.getFromWarehouseId() != null, ErpStockMoveItemDO::getFromWarehouseId, reqVO.getFromWarehouseId())
  31 + .eq(reqVO.getProductId() != null, ErpStockMoveItemDO::getProductId, reqVO.getProductId())
  32 + .groupBy(ErpStockMoveDO::getId); // 避免 1 对多查询,产生相同的 1
  33 + }
  34 + return selectJoinPage(reqVO, ErpStockMoveDO.class, query);
  35 + }
  36 +
  37 + default int updateByIdAndStatus(Long id, Integer status, ErpStockMoveDO updateObj) {
  38 + return update(updateObj, new LambdaUpdateWrapper<ErpStockMoveDO>()
  39 + .eq(ErpStockMoveDO::getId, id).eq(ErpStockMoveDO::getStatus, status));
  40 + }
  41 +
  42 + default ErpStockMoveDO selectByNo(String no) {
  43 + return selectOne(ErpStockMoveDO::getNo, no);
  44 + }
  45 +
  46 +}
0 47 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutItemMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * ERP 其它出库单项 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface ErpStockOutItemMapper extends BaseMapperX<ErpStockOutItemDO> {
  17 +
  18 + default List<ErpStockOutItemDO> selectListByOutId(Long outId) {
  19 + return selectList(ErpStockOutItemDO::getOutId, outId);
  20 + }
  21 +
  22 + default List<ErpStockOutItemDO> selectListByOutIds(Collection<Long> outIds) {
  23 + return selectList(ErpStockOutItemDO::getOutId, outIds);
  24 + }
  25 +
  26 + default int deleteByOutId(Long outId) {
  27 + return delete(ErpStockOutItemDO::getOutId, outId);
  28 + }
  29 +
  30 +}
0 31 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
  9 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +/**
  13 + * ERP 其它出库单 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpStockOutMapper extends BaseMapperX<ErpStockOutDO> {
  19 +
  20 + default PageResult<ErpStockOutDO> selectPage(ErpStockOutPageReqVO reqVO) {
  21 + MPJLambdaWrapperX<ErpStockOutDO> query = new MPJLambdaWrapperX<ErpStockOutDO>()
  22 + .eqIfPresent(ErpStockOutDO::getNo, reqVO.getNo())
  23 + .eqIfPresent(ErpStockOutDO::getCustomerId, reqVO.getCustomerId())
  24 + .betweenIfPresent(ErpStockOutDO::getOutTime, reqVO.getOutTime())
  25 + .eqIfPresent(ErpStockOutDO::getStatus, reqVO.getStatus())
  26 + .likeIfPresent(ErpStockOutDO::getRemark, reqVO.getRemark())
  27 + .eqIfPresent(ErpStockOutDO::getCreator, reqVO.getCreator())
  28 + .orderByDesc(ErpStockOutDO::getId);
  29 + if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
  30 + query.leftJoin(ErpStockOutItemDO.class, ErpStockOutItemDO::getOutId, ErpStockOutDO::getId)
  31 + .eq(reqVO.getWarehouseId() != null, ErpStockOutItemDO::getWarehouseId, reqVO.getWarehouseId())
  32 + .eq(reqVO.getProductId() != null, ErpStockOutItemDO::getProductId, reqVO.getProductId())
  33 + .groupBy(ErpStockOutDO::getId); // 避免 1 对多查询,产生相同的 1
  34 + }
  35 + return selectJoinPage(reqVO, ErpStockOutDO.class, query);
  36 + }
  37 +
  38 + default int updateByIdAndStatus(Long id, Integer status, ErpStockOutDO updateObj) {
  39 + return update(updateObj, new LambdaUpdateWrapper<ErpStockOutDO>()
  40 + .eq(ErpStockOutDO::getId, id).eq(ErpStockOutDO::getStatus, status));
  41 + }
  42 +
  43 + default ErpStockOutDO selectByNo(String no) {
  44 + return selectOne(ErpStockOutDO::getNo, no);
  45 + }
  46 +
  47 +}
0 48 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockRecordMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +/**
  11 + * ERP 产品库存明细 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface ErpStockRecordMapper extends BaseMapperX<ErpStockRecordDO> {
  17 +
  18 + default PageResult<ErpStockRecordDO> selectPage(ErpStockRecordPageReqVO reqVO) {
  19 + return selectPage(reqVO, new LambdaQueryWrapperX<ErpStockRecordDO>()
  20 + .eqIfPresent(ErpStockRecordDO::getProductId, reqVO.getProductId())
  21 + .eqIfPresent(ErpStockRecordDO::getWarehouseId, reqVO.getWarehouseId())
  22 + .eqIfPresent(ErpStockRecordDO::getBizType, reqVO.getBizType())
  23 + .likeIfPresent(ErpStockRecordDO::getBizNo, reqVO.getBizNo())
  24 + .betweenIfPresent(ErpStockRecordDO::getCreateTime, reqVO.getCreateTime())
  25 + .orderByDesc(ErpStockRecordDO::getId));
  26 + }
  27 +
  28 +}
0 29 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpWarehouseMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * ERP 仓库 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpWarehouseMapper extends BaseMapperX<ErpWarehouseDO> {
  19 +
  20 + default PageResult<ErpWarehouseDO> selectPage(ErpWarehousePageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<ErpWarehouseDO>()
  22 + .likeIfPresent(ErpWarehouseDO::getName, reqVO.getName())
  23 + .eqIfPresent(ErpWarehouseDO::getStatus, reqVO.getStatus())
  24 + .orderByDesc(ErpWarehouseDO::getId));
  25 + }
  26 +
  27 + default ErpWarehouseDO selectByDefaultStatus() {
  28 + return selectOne(ErpWarehouseDO::getDefaultStatus, true);
  29 + }
  30 +
  31 + default List<ErpWarehouseDO> selectListByStatus(Integer status) {
  32 + return selectList(ErpWarehouseDO::getStatus, status);
  33 + }
  34 +
  35 +}
0 36 \ 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
  1 +package cn.iocoder.yudao.module.erp.dal.redis;
  2 +
  3 +/**
  4 + * ERP Redis Key 枚举类
  5 + *
  6 + * @author 芋道源码
  7 + */
  8 +public interface RedisKeyConstants {
  9 +
  10 + /**
  11 + * 序号的缓存
  12 + *
  13 + * KEY 格式:trade_no:{prefix}
  14 + * VALUE 数据格式:编号自增
  15 + */
  16 + String NO = "seq_no:";
  17 +
  18 +}
... ...
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 + * 其它入库 {@link cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO}
  24 + */
  25 + public static final String STOCK_IN_NO_PREFIX = "QTRK";
  26 + /**
  27 + * 其它出库 {@link cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO}
  28 + */
  29 + public static final String STOCK_OUT_NO_PREFIX = "QCKD";
  30 +
  31 + /**
  32 + * 库存调拨 {@link cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO}
  33 + */
  34 + public static final String STOCK_MOVE_NO_PREFIX = "QCDB";
  35 +
  36 + /**
  37 + * 库存盘点 {@link cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO}
  38 + */
  39 + public static final String STOCK_CHECK_NO_PREFIX = "QCPD";
  40 +
  41 + @Resource
  42 + private StringRedisTemplate stringRedisTemplate;
  43 +
  44 + /**
  45 + * 生成序号,使用当前日期,格式为 {PREFIX} + yyyyMMdd + 6 位自增
  46 + * 例如说:QTRK 202109 000001 (没有中间空格)
  47 + *
  48 + * @param prefix 前缀
  49 + * @return 序号
  50 + */
  51 + public String generate(String prefix) {
  52 + // 递增序号
  53 + String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN);
  54 + String key = RedisKeyConstants.NO + noPrefix;
  55 + Long no = stringRedisTemplate.opsForValue().increment(key);
  56 + // 设置过期时间
  57 + stringRedisTemplate.expire(key, Duration.ofMinutes(1L));
  58 + return noPrefix + String.format("%06d", no);
  59 + }
  60 +
  61 +}
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductCategoryService.java
... ... @@ -5,7 +5,11 @@ import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProdu
5 5 import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
6 6 import jakarta.validation.Valid;
7 7  
  8 +import java.util.Collection;
8 9 import java.util.List;
  10 +import java.util.Map;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
9 13  
10 14 /**
11 15 * ERP 产品分类 Service 接口
... ... @@ -40,7 +44,7 @@ public interface ErpProductCategoryService {
40 44 * 获得产品分类
41 45 *
42 46 * @param id 编号
43   - * @return ERP 产品分类
  47 + * @return 产品分类
44 48 */
45 49 ErpProductCategoryDO getProductCategory(Long id);
46 50  
... ... @@ -48,8 +52,26 @@ public interface ErpProductCategoryService {
48 52 * 获得产品分类列表
49 53 *
50 54 * @param listReqVO 查询条件
51   - * @return ERP 产品分类列表
  55 + * @return 产品分类列表
52 56 */
53 57 List<ErpProductCategoryDO> getProductCategoryList(ErpProductCategoryListReqVO listReqVO);
54 58  
  59 + /**
  60 + * 获得产品分类列表
  61 + *
  62 + * @param ids 编号数组
  63 + * @return 产品分类列表
  64 + */
  65 + List<ErpProductCategoryDO> getProductCategoryList(Collection<Long> ids);
  66 +
  67 + /**
  68 + * 获得产品分类 Map
  69 + *
  70 + * @param ids 编号数组
  71 + * @return 产品分类 Map
  72 + */
  73 + default Map<Long, ErpProductCategoryDO> getProductCategoryMap(Collection<Long> ids) {
  74 + return convertMap(getProductCategoryList(ids), ErpProductCategoryDO::getId);
  75 + }
  76 +
55 77 }
56 78 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductCategoryServiceImpl.java
... ... @@ -6,14 +6,16 @@ import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProdu
6 6 import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
7 7 import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductCategoryMapper;
8 8 import jakarta.annotation.Resource;
  9 +import org.springframework.context.annotation.Lazy;
9 10 import org.springframework.stereotype.Service;
10 11 import org.springframework.validation.annotation.Validated;
11 12  
  13 +import java.util.Collection;
12 14 import java.util.List;
13 15 import java.util.Objects;
14 16  
15 17 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16   -import static cn.iocoder.yudao.module.erp.ErrorCodeConstants.*;
  18 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
17 19  
18 20 /**
19 21 * ERP 产品分类 Service 实现类
... ... @@ -27,6 +29,10 @@ public class ErpProductCategoryServiceImpl implements ErpProductCategoryService
27 29 @Resource
28 30 private ErpProductCategoryMapper productCategoryMapper;
29 31  
  32 + @Resource
  33 + @Lazy // 延迟加载,避免循环依赖
  34 + private ErpProductService productService;
  35 +
30 36 @Override
31 37 public Long createProductCategory(ErpProductCategorySaveReqVO createReqVO) {
32 38 // 校验父分类编号的有效性
... ... @@ -57,13 +63,17 @@ public class ErpProductCategoryServiceImpl implements ErpProductCategoryService
57 63  
58 64 @Override
59 65 public void deleteProductCategory(Long id) {
60   - // 校验存在
  66 + // 1.1 校验存在
61 67 validateProductCategoryExists(id);
62   - // 校验是否有子产品分类
  68 + // 1.2 校验是否有子产品分类
63 69 if (productCategoryMapper.selectCountByParentId(id) > 0) {
64 70 throw exception(PRODUCT_CATEGORY_EXITS_CHILDREN);
65 71 }
66   - // 删除
  72 + // 1.3 校验是否有产品
  73 + if (productService.getProductCountByCategoryId(id) > 0) {
  74 + throw exception(PRODUCT_CATEGORY_EXITS_PRODUCT);
  75 + }
  76 + // 2. 删除
67 77 productCategoryMapper.deleteById(id);
68 78 }
69 79  
... ... @@ -131,4 +141,9 @@ public class ErpProductCategoryServiceImpl implements ErpProductCategoryService
131 141 return productCategoryMapper.selectList(listReqVO);
132 142 }
133 143  
  144 + @Override
  145 + public List<ErpProductCategoryDO> getProductCategoryList(Collection<Long> ids) {
  146 + return productCategoryMapper.selectBatchIds(ids);
  147 + }
  148 +
134 149 }
135 150 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductService.java
1 1 package cn.iocoder.yudao.module.erp.service.product;
2 2  
3   -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPageReqVO;
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
4 6 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO;
5   -import jakarta.validation.*;
6 7 import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
7   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
8 15  
9 16 /**
10 17 * ERP 产品 Service 接口
... ... @@ -36,6 +43,14 @@ public interface ErpProductService {
36 43 void deleteProduct(Long id);
37 44  
38 45 /**
  46 + * 校验产品们的有效性
  47 + *
  48 + * @param ids 编号数组
  49 + * @return 产品列表
  50 + */
  51 + List<ErpProductDO> validProductList(Collection<Long> ids);
  52 +
  53 + /**
39 54 * 获得产品
40 55 *
41 56 * @param id 编号
... ... @@ -44,11 +59,53 @@ public interface ErpProductService {
44 59 ErpProductDO getProduct(Long id);
45 60  
46 61 /**
47   - * 获得产品分页
  62 + * 获得指定状态的产品 VO 列表
  63 + *
  64 + * @param status 状态
  65 + * @return 产品 VO 列表
  66 + */
  67 + List<ErpProductRespVO> getProductVOListByStatus(Integer status);
  68 +
  69 + /**
  70 + * 获得产品 VO 列表
  71 + *
  72 + * @param ids 编号数组
  73 + * @return 产品 VO 列表
  74 + */
  75 + List<ErpProductRespVO> getProductVOList(Collection<Long> ids);
  76 +
  77 + /**
  78 + * 获得产品 VO Map
  79 + *
  80 + * @param ids 编号数组
  81 + * @return 产品 VO Map
  82 + */
  83 + default Map<Long, ErpProductRespVO> getProductVOMap(Collection<Long> ids) {
  84 + return convertMap(getProductVOList(ids), ErpProductRespVO::getId);
  85 + }
  86 +
  87 + /**
  88 + * 获得产品 VO 分页
48 89 *
49 90 * @param pageReqVO 分页查询
50 91 * @return 产品分页
51 92 */
52   - PageResult<ErpProductDO> getProductPage(ProductPageReqVO pageReqVO);
  93 + PageResult<ErpProductRespVO> getProductVOPage(ErpProductPageReqVO pageReqVO);
  94 +
  95 + /**
  96 + * 基于产品分类编号,获得产品数量
  97 + *
  98 + * @param categoryId 产品分类编号
  99 + * @return 产品数量
  100 + */
  101 + Long getProductCountByCategoryId(Long categoryId);
  102 +
  103 + /**
  104 + * 基于产品单位编号,获得产品数量
  105 + *
  106 + * @param unitId 产品单位编号
  107 + * @return 产品数量
  108 + */
  109 + Long getProductCountByUnitId(Long unitId);
53 110  
54 111 }
55 112 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductServiceImpl.java
1 1 package cn.iocoder.yudao.module.erp.service.product;
2 2  
3   -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPageReqVO;
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
  9 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
4 10 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO;
5   -import org.springframework.stereotype.Service;
  11 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
  12 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  13 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
  14 +import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
6 15 import jakarta.annotation.Resource;
  16 +import org.springframework.stereotype.Service;
7 17 import org.springframework.validation.annotation.Validated;
8 18  
9   -import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
10   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
11   -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
12   -
13   -import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
  19 +import java.util.*;
14 20  
15 21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16   -import static cn.iocoder.yudao.module.erp.ErrorCodeConstants.PRODUCT_NOT_EXISTS;
  22 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  23 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
17 24  
18 25 /**
19 26 * ERP 产品 Service 实现类
... ... @@ -27,8 +34,14 @@ public class ErpProductServiceImpl implements ErpProductService {
27 34 @Resource
28 35 private ErpProductMapper productMapper;
29 36  
  37 + @Resource
  38 + private ErpProductCategoryService productCategoryService;
  39 + @Resource
  40 + private ErpProductUnitService productUnitService;
  41 +
30 42 @Override
31 43 public Long createProduct(ProductSaveReqVO createReqVO) {
  44 + // TODO 芋艿:校验分类
32 45 // 插入
33 46 ErpProductDO product = BeanUtils.toBean(createReqVO, ErpProductDO.class);
34 47 productMapper.insert(product);
... ... @@ -38,6 +51,7 @@ public class ErpProductServiceImpl implements ErpProductService {
38 51  
39 52 @Override
40 53 public void updateProduct(ProductSaveReqVO updateReqVO) {
  54 + // TODO 芋艿:校验分类
41 55 // 校验存在
42 56 validateProductExists(updateReqVO.getId());
43 57 // 更新
... ... @@ -53,6 +67,25 @@ public class ErpProductServiceImpl implements ErpProductService {
53 67 productMapper.deleteById(id);
54 68 }
55 69  
  70 + @Override
  71 + public List<ErpProductDO> validProductList(Collection<Long> ids) {
  72 + if (CollUtil.isEmpty(ids)) {
  73 + return Collections.emptyList();
  74 + }
  75 + List<ErpProductDO> list = productMapper.selectBatchIds(ids);
  76 + Map<Long, ErpProductDO> productMap = convertMap(list, ErpProductDO::getId);
  77 + for (Long id : ids) {
  78 + ErpProductDO product = productMap.get(id);
  79 + if (productMap.get(id) == null) {
  80 + throw exception(PRODUCT_NOT_EXISTS);
  81 + }
  82 + if (CommonStatusEnum.isDisable(product.getStatus())) {
  83 + throw exception(PRODUCT_NOT_ENABLE, product.getName());
  84 + }
  85 + }
  86 + return list;
  87 + }
  88 +
56 89 private void validateProductExists(Long id) {
57 90 if (productMapper.selectById(id) == null) {
58 91 throw exception(PRODUCT_NOT_EXISTS);
... ... @@ -65,8 +98,47 @@ public class ErpProductServiceImpl implements ErpProductService {
65 98 }
66 99  
67 100 @Override
68   - public PageResult<ErpProductDO> getProductPage(ProductPageReqVO pageReqVO) {
69   - return productMapper.selectPage(pageReqVO);
  101 + public List<ErpProductRespVO> getProductVOListByStatus(Integer status) {
  102 + List<ErpProductDO> list = productMapper.selectListByStatus(status);
  103 + return buildProductVOList(list);
  104 + }
  105 +
  106 + @Override
  107 + public List<ErpProductRespVO> getProductVOList(Collection<Long> ids) {
  108 + List<ErpProductDO> list = productMapper.selectBatchIds(ids);
  109 + return buildProductVOList(list);
  110 + }
  111 +
  112 + @Override
  113 + public PageResult<ErpProductRespVO> getProductVOPage(ErpProductPageReqVO pageReqVO) {
  114 + PageResult<ErpProductDO> pageResult = productMapper.selectPage(pageReqVO);
  115 + return new PageResult<>(buildProductVOList(pageResult.getList()), pageResult.getTotal());
  116 + }
  117 +
  118 + private List<ErpProductRespVO> buildProductVOList(List<ErpProductDO> list) {
  119 + if (CollUtil.isEmpty(list)) {
  120 + return Collections.emptyList();
  121 + }
  122 + Map<Long, ErpProductCategoryDO> categoryMap = productCategoryService.getProductCategoryMap(
  123 + convertSet(list, ErpProductDO::getCategoryId));
  124 + Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
  125 + convertSet(list, ErpProductDO::getUnitId));
  126 + return BeanUtils.toBean(list, ErpProductRespVO.class, product -> {
  127 + MapUtils.findAndThen(categoryMap, product.getCategoryId(),
  128 + category -> product.setCategoryName(category.getName()));
  129 + MapUtils.findAndThen(unitMap, product.getUnitId(),
  130 + unit -> product.setUnitName(unit.getName()));
  131 + });
  132 + }
  133 +
  134 + @Override
  135 + public Long getProductCountByCategoryId(Long categoryId) {
  136 + return productMapper.selectCountByCategoryId(categoryId);
  137 + }
  138 +
  139 + @Override
  140 + public Long getProductCountByUnitId(Long unitId) {
  141 + return productMapper.selectCountByUnitId(unitId);
70 142 }
71 143  
72 144 }
73 145 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductUnitService.java
1 1 package cn.iocoder.yudao.module.erp.service.product;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 4 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitPageReqVO;
4 5 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO;
5   -import jakarta.validation.*;
6 6 import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
7   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
8 14  
9 15 /**
10 16 * ERP 产品单位 Service 接口
... ... @@ -51,4 +57,30 @@ public interface ErpProductUnitService {
51 57 */
52 58 PageResult<ErpProductUnitDO> getProductUnitPage(ErpProductUnitPageReqVO pageReqVO);
53 59  
  60 + /**
  61 + * 获得指定状态的产品单位列表
  62 + *
  63 + * @param status 状态
  64 + * @return 产品单位列表
  65 + */
  66 + List<ErpProductUnitDO> getProductUnitListByStatus(Integer status);
  67 +
  68 + /**
  69 + * 获得产品单位列表
  70 + *
  71 + * @param ids 编号数组
  72 + * @return 产品单位列表
  73 + */
  74 + List<ErpProductUnitDO> getProductUnitList(Collection<Long> ids);
  75 +
  76 + /**
  77 + * 获得产品单位 Map
  78 + *
  79 + * @param ids 编号数组
  80 + * @return 产品单位 Map
  81 + */
  82 + default Map<Long, ErpProductUnitDO> getProductUnitMap(Collection<Long> ids) {
  83 + return convertMap(getProductUnitList(ids), ErpProductUnitDO::getId);
  84 + }
  85 +
54 86 }
55 87 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductUnitServiceImpl.java
1 1 package cn.iocoder.yudao.module.erp.service.product;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
3 5 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitPageReqVO;
4 6 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO;
5   -import org.springframework.stereotype.Service;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
  8 +import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductUnitMapper;
  9 +import com.google.common.annotations.VisibleForTesting;
6 10 import jakarta.annotation.Resource;
  11 +import org.springframework.context.annotation.Lazy;
  12 +import org.springframework.stereotype.Service;
7 13 import org.springframework.validation.annotation.Validated;
8 14  
9   -import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
10   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
11   -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
12   -
13   -import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductUnitMapper;
  15 +import java.util.Collection;
  16 +import java.util.List;
14 17  
15 18 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16   -import static cn.iocoder.yudao.module.erp.ErrorCodeConstants.PRODUCT_UNIT_NOT_EXISTS;
  19 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
17 20  
18 21 /**
19 22 * ERP 产品单位 Service 实现类
... ... @@ -27,29 +30,55 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
27 30 @Resource
28 31 private ErpProductUnitMapper productUnitMapper;
29 32  
  33 + @Resource
  34 + @Lazy // 延迟加载,避免循环依赖
  35 + private ErpProductService productService;
  36 +
30 37 @Override
31 38 public Long createProductUnit(ErpProductUnitSaveReqVO createReqVO) {
32   - // 插入
  39 + // 1. 校验名字唯一
  40 + validateProductUnitNameUnique(null, createReqVO.getName());
  41 + // 2. 插入
33 42 ErpProductUnitDO unit = BeanUtils.toBean(createReqVO, ErpProductUnitDO.class);
34 43 productUnitMapper.insert(unit);
35   - // 返回
36 44 return unit.getId();
37 45 }
38 46  
39 47 @Override
40 48 public void updateProductUnit(ErpProductUnitSaveReqVO updateReqVO) {
41   - // 校验存在
  49 + // 1.1 校验存在
42 50 validateProductUnitExists(updateReqVO.getId());
43   - // 更新
  51 + // 1.2 校验名字唯一
  52 + validateProductUnitNameUnique(updateReqVO.getId(), updateReqVO.getName());
  53 + // 2. 更新
44 54 ErpProductUnitDO updateObj = BeanUtils.toBean(updateReqVO, ErpProductUnitDO.class);
45 55 productUnitMapper.updateById(updateObj);
46 56 }
47 57  
  58 + @VisibleForTesting
  59 + void validateProductUnitNameUnique(Long id, String name) {
  60 + ErpProductUnitDO unit = productUnitMapper.selectByName(name);
  61 + if (unit == null) {
  62 + return;
  63 + }
  64 + // 如果 id 为空,说明不用比较是否为相同 id 的字典类型
  65 + if (id == null) {
  66 + throw exception(PRODUCT_UNIT_NAME_DUPLICATE);
  67 + }
  68 + if (!unit.getId().equals(id)) {
  69 + throw exception(PRODUCT_UNIT_NAME_DUPLICATE);
  70 + }
  71 + }
  72 +
48 73 @Override
49 74 public void deleteProductUnit(Long id) {
50   - // 校验存在
  75 + // 1.1 校验存在
51 76 validateProductUnitExists(id);
52   - // 删除
  77 + // 1.2 校验商品是否使用
  78 + if (productService.getProductCountByUnitId(id) > 0) {
  79 + throw exception(PRODUCT_UNIT_EXITS_PRODUCT);
  80 + }
  81 + // 2. 删除
53 82 productUnitMapper.deleteById(id);
54 83 }
55 84  
... ... @@ -69,4 +98,14 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
69 98 return productUnitMapper.selectPage(pageReqVO);
70 99 }
71 100  
  101 + @Override
  102 + public List<ErpProductUnitDO> getProductUnitListByStatus(Integer status) {
  103 + return productUnitMapper.selectListByStatus(status);
  104 + }
  105 +
  106 + @Override
  107 + public List<ErpProductUnitDO> getProductUnitList(Collection<Long> ids) {
  108 + return productUnitMapper.selectBatchIds(ids);
  109 + }
  110 +
72 111 }
73 112 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpSupplierService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  14 +
  15 +/**
  16 + * ERP 供应商 Service 接口
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +public interface ErpSupplierService {
  21 +
  22 + /**
  23 + * 创建供应商
  24 + *
  25 + * @param createReqVO 创建信息
  26 + * @return 编号
  27 + */
  28 + Long createSupplier(@Valid ErpSupplierSaveReqVO createReqVO);
  29 +
  30 + /**
  31 + * 更新供应商
  32 + *
  33 + * @param updateReqVO 更新信息
  34 + */
  35 + void updateSupplier(@Valid ErpSupplierSaveReqVO updateReqVO);
  36 +
  37 + /**
  38 + * 删除供应商
  39 + *
  40 + * @param id 编号
  41 + */
  42 + void deleteSupplier(Long id);
  43 +
  44 + /**
  45 + * 获得供应商
  46 + *
  47 + * @param id 编号
  48 + * @return 供应商
  49 + */
  50 + ErpSupplierDO getSupplier(Long id);
  51 +
  52 + /**
  53 + * 校验供应商
  54 + *
  55 + * @param id 编号
  56 + * @return 供应商
  57 + */
  58 + ErpSupplierDO validateSupplier(Long id);
  59 +
  60 + /**
  61 + * 获得供应商列表
  62 + *
  63 + * @param ids 编号列表
  64 + * @return 供应商列表
  65 + */
  66 + List<ErpSupplierDO> getSupplierList(Collection<Long> ids);
  67 +
  68 + /**
  69 + * 获得供应商 Map
  70 + *
  71 + * @param ids 编号列表
  72 + * @return 供应商 Map
  73 + */
  74 + default Map<Long, ErpSupplierDO> getSupplierMap(Collection<Long> ids) {
  75 + return convertMap(getSupplierList(ids), ErpSupplierDO::getId);
  76 + }
  77 +
  78 + /**
  79 + * 获得供应商分页
  80 + *
  81 + * @param pageReqVO 分页查询
  82 + * @return 供应商分页
  83 + */
  84 + PageResult<ErpSupplierDO> getSupplierPage(ErpSupplierPageReqVO pageReqVO);
  85 +
  86 + /**
  87 + * 获得指定状态的供应商列表
  88 + *
  89 + * @param status 状态
  90 + * @return 供应商列表
  91 + */
  92 + List<ErpSupplierDO> getSupplierListByStatus(Integer status);
  93 +
  94 +}
0 95 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpSupplierServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierSaveReqVO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  9 +import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpSupplierMapper;
  10 +import jakarta.annotation.Resource;
  11 +import org.springframework.stereotype.Service;
  12 +import org.springframework.validation.annotation.Validated;
  13 +
  14 +import java.util.Collection;
  15 +import java.util.List;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  18 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  19 +
  20 +/**
  21 + * ERP 供应商 Service 实现类
  22 + *
  23 + * @author 芋道源码
  24 + */
  25 +@Service
  26 +@Validated
  27 +public class ErpSupplierServiceImpl implements ErpSupplierService {
  28 +
  29 + @Resource
  30 + private ErpSupplierMapper supplierMapper;
  31 +
  32 + @Override
  33 + public Long createSupplier(ErpSupplierSaveReqVO createReqVO) {
  34 + ErpSupplierDO supplier = BeanUtils.toBean(createReqVO, ErpSupplierDO.class);
  35 + supplierMapper.insert(supplier);
  36 + return supplier.getId();
  37 + }
  38 +
  39 + @Override
  40 + public void updateSupplier(ErpSupplierSaveReqVO updateReqVO) {
  41 + // 校验存在
  42 + validateSupplierExists(updateReqVO.getId());
  43 + // 更新
  44 + ErpSupplierDO updateObj = BeanUtils.toBean(updateReqVO, ErpSupplierDO.class);
  45 + supplierMapper.updateById(updateObj);
  46 + }
  47 +
  48 + @Override
  49 + public void deleteSupplier(Long id) {
  50 + // 校验存在
  51 + validateSupplierExists(id);
  52 + // 删除
  53 + supplierMapper.deleteById(id);
  54 + }
  55 +
  56 + private void validateSupplierExists(Long id) {
  57 + if (supplierMapper.selectById(id) == null) {
  58 + throw exception(SUPPLIER_NOT_EXISTS);
  59 + }
  60 + }
  61 +
  62 + @Override
  63 + public ErpSupplierDO getSupplier(Long id) {
  64 + return supplierMapper.selectById(id);
  65 + }
  66 +
  67 + @Override
  68 + public ErpSupplierDO validateSupplier(Long id) {
  69 + ErpSupplierDO supplier = supplierMapper.selectById(id);
  70 + if (supplier == null) {
  71 + throw exception(WAREHOUSE_NOT_EXISTS);
  72 + }
  73 + if (CommonStatusEnum.isDisable(supplier.getStatus())) {
  74 + throw exception(WAREHOUSE_NOT_ENABLE, supplier.getName());
  75 + }
  76 + return supplier;
  77 + }
  78 +
  79 + @Override
  80 + public List<ErpSupplierDO> getSupplierList(Collection<Long> ids) {
  81 + return supplierMapper.selectBatchIds(ids);
  82 + }
  83 +
  84 + @Override
  85 + public PageResult<ErpSupplierDO> getSupplierPage(ErpSupplierPageReqVO pageReqVO) {
  86 + return supplierMapper.selectPage(pageReqVO);
  87 + }
  88 +
  89 + @Override
  90 + public List<ErpSupplierDO> getSupplierListByStatus(Integer status) {
  91 + return supplierMapper.selectListByStatus(status);
  92 + }
  93 +
  94 +}
0 95 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.sale;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  14 +
  15 +/**
  16 + * ERP 客户 Service 接口
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +public interface ErpCustomerService {
  21 +
  22 + /**
  23 + * 创建客户
  24 + *
  25 + * @param createReqVO 创建信息
  26 + * @return 编号
  27 + */
  28 + Long createCustomer(@Valid ErpCustomerSaveReqVO createReqVO);
  29 +
  30 + /**
  31 + * 更新客户
  32 + *
  33 + * @param updateReqVO 更新信息
  34 + */
  35 + void updateCustomer(@Valid ErpCustomerSaveReqVO updateReqVO);
  36 +
  37 + /**
  38 + * 删除客户
  39 + *
  40 + * @param id 编号
  41 + */
  42 + void deleteCustomer(Long id);
  43 +
  44 + /**
  45 + * 获得客户
  46 + *
  47 + * @param id 编号
  48 + * @return 客户
  49 + */
  50 + ErpCustomerDO getCustomer(Long id);
  51 +
  52 + /**
  53 + * 校验客户
  54 + *
  55 + * @param id 编号
  56 + * @return 客户
  57 + */
  58 + ErpCustomerDO validateCustomer(Long id);
  59 +
  60 + /**
  61 + * 获得客户列表
  62 + *
  63 + * @param ids 编号列表
  64 + * @return 客户列表
  65 + */
  66 + List<ErpCustomerDO> getCustomerList(Collection<Long> ids);
  67 +
  68 + /**
  69 + * 获得客户 Map
  70 + *
  71 + * @param ids 编号列表
  72 + * @return 客户 Map
  73 + */
  74 + default Map<Long, ErpCustomerDO> getCustomerMap(Collection<Long> ids) {
  75 + return convertMap(getCustomerList(ids), ErpCustomerDO::getId);
  76 + }
  77 +
  78 + /**
  79 + * 获得客户分页
  80 + *
  81 + * @param pageReqVO 分页查询
  82 + * @return 客户分页
  83 + */
  84 + PageResult<ErpCustomerDO> getCustomerPage(ErpCustomerPageReqVO pageReqVO);
  85 +
  86 + /**
  87 + * 获得指定状态的客户列表
  88 + *
  89 + * @param status 状态
  90 + * @return 客户列表
  91 + */
  92 + List<ErpCustomerDO> getCustomerListByStatus(Integer status);
  93 +
  94 +}
0 95 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.sale;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
  9 +import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpCustomerMapper;
  10 +import jakarta.annotation.Resource;
  11 +import org.springframework.stereotype.Service;
  12 +import org.springframework.validation.annotation.Validated;
  13 +
  14 +import java.util.Collection;
  15 +import java.util.List;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  18 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.CUSTOMER_NOT_ENABLE;
  19 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
  20 +
  21 +/**
  22 + * ERP 客户 Service 实现类
  23 + *
  24 + * @author 芋道源码
  25 + */
  26 +@Service
  27 +@Validated
  28 +public class ErpCustomerServiceImpl implements ErpCustomerService {
  29 +
  30 + @Resource
  31 + private ErpCustomerMapper customerMapper;
  32 +
  33 + @Override
  34 + public Long createCustomer(ErpCustomerSaveReqVO createReqVO) {
  35 + // 插入
  36 + ErpCustomerDO customer = BeanUtils.toBean(createReqVO, ErpCustomerDO.class);
  37 + customerMapper.insert(customer);
  38 + // 返回
  39 + return customer.getId();
  40 + }
  41 +
  42 + @Override
  43 + public void updateCustomer(ErpCustomerSaveReqVO updateReqVO) {
  44 + // 校验存在
  45 + validateCustomerExists(updateReqVO.getId());
  46 + // 更新
  47 + ErpCustomerDO updateObj = BeanUtils.toBean(updateReqVO, ErpCustomerDO.class);
  48 + customerMapper.updateById(updateObj);
  49 + }
  50 +
  51 + @Override
  52 + public void deleteCustomer(Long id) {
  53 + // 校验存在
  54 + validateCustomerExists(id);
  55 + // 删除
  56 + customerMapper.deleteById(id);
  57 + }
  58 +
  59 + private void validateCustomerExists(Long id) {
  60 + if (customerMapper.selectById(id) == null) {
  61 + throw exception(CUSTOMER_NOT_EXISTS);
  62 + }
  63 + }
  64 +
  65 + @Override
  66 + public ErpCustomerDO getCustomer(Long id) {
  67 + return customerMapper.selectById(id);
  68 + }
  69 +
  70 + @Override
  71 + public ErpCustomerDO validateCustomer(Long id) {
  72 + ErpCustomerDO customer = customerMapper.selectById(id);
  73 + if (customer == null) {
  74 + throw exception(CUSTOMER_NOT_EXISTS);
  75 + }
  76 + if (CommonStatusEnum.isDisable(customer.getStatus())) {
  77 + throw exception(CUSTOMER_NOT_ENABLE, customer.getName());
  78 + }
  79 + return customer;
  80 + }
  81 +
  82 + @Override
  83 + public List<ErpCustomerDO> getCustomerList(Collection<Long> ids) {
  84 + return customerMapper.selectBatchIds(ids);
  85 + }
  86 +
  87 + @Override
  88 + public PageResult<ErpCustomerDO> getCustomerPage(ErpCustomerPageReqVO pageReqVO) {
  89 + return customerMapper.selectPage(pageReqVO);
  90 + }
  91 +
  92 + @Override
  93 + public List<ErpCustomerDO> getCustomerListByStatus(Integer status) {
  94 + return customerMapper.selectListByStatus(status);
  95 + }
  96 +
  97 +}
0 98 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * ERP 库存盘点单 Service 接口
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +public interface ErpStockCheckService {
  19 +
  20 + /**
  21 + * 创建库存盘点单
  22 + *
  23 + * @param createReqVO 创建信息
  24 + * @return 编号
  25 + */
  26 + Long createStockCheck(@Valid ErpStockCheckSaveReqVO createReqVO);
  27 +
  28 + /**
  29 + * 更新库存盘点单
  30 + *
  31 + * @param updateReqVO 更新信息
  32 + */
  33 + void updateStockCheck(@Valid ErpStockCheckSaveReqVO updateReqVO);
  34 +
  35 + /**
  36 + * 更新库存盘点单的状态
  37 + *
  38 + * @param id 编号
  39 + * @param status 状态
  40 + */
  41 + void updateStockCheckStatus(Long id, Integer status);
  42 +
  43 + /**
  44 + * 删除库存盘点单
  45 + *
  46 + * @param ids 编号数组
  47 + */
  48 + void deleteStockCheck(List<Long> ids);
  49 +
  50 + /**
  51 + * 获得库存盘点单
  52 + *
  53 + * @param id 编号
  54 + * @return 库存盘点单
  55 + */
  56 + ErpStockCheckDO getStockCheck(Long id);
  57 +
  58 + /**
  59 + * 获得库存盘点单分页
  60 + *
  61 + * @param pageReqVO 分页查询
  62 + * @return 库存盘点单分页
  63 + */
  64 + PageResult<ErpStockCheckDO> getStockCheckPage(ErpStockCheckPageReqVO pageReqVO);
  65 +
  66 + // ==================== 盘点项 ====================
  67 +
  68 + /**
  69 + * 获得库存盘点单项列表
  70 + *
  71 + * @param checkId 盘点编号
  72 + * @return 库存盘点单项列表
  73 + */
  74 + List<ErpStockCheckItemDO> getStockCheckItemListByCheckId(Long checkId);
  75 +
  76 + /**
  77 + * 获得库存盘点单项 List
  78 + *
  79 + * @param checkIds 盘点编号数组
  80 + * @return 库存盘点单项 List
  81 + */
  82 + List<ErpStockCheckItemDO> getStockCheckItemListByCheckIds(Collection<Long> checkIds);
  83 +
  84 +}
0 85 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO;
  8 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO;
  9 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  10 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO;
  11 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
  12 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockCheckItemMapper;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockCheckMapper;
  14 +import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
  15 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  16 +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
  17 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  18 +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
  19 +import jakarta.annotation.Resource;
  20 +import org.springframework.stereotype.Service;
  21 +import org.springframework.transaction.annotation.Transactional;
  22 +import org.springframework.validation.annotation.Validated;
  23 +
  24 +import java.math.BigDecimal;
  25 +import java.util.Collection;
  26 +import java.util.Collections;
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  32 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  33 +
  34 +// TODO 芋艿:记录操作日志
  35 +
  36 +/**
  37 + * ERP 库存盘点单 Service 实现类
  38 + *
  39 + * @author 芋道源码
  40 + */
  41 +@Service
  42 +@Validated
  43 +public class ErpStockCheckServiceImpl implements ErpStockCheckService {
  44 +
  45 + @Resource
  46 + private ErpStockCheckMapper stockCheckMapper;
  47 + @Resource
  48 + private ErpStockCheckItemMapper stockCheckItemMapper;
  49 +
  50 + @Resource
  51 + private ErpNoRedisDAO noRedisDAO;
  52 +
  53 + @Resource
  54 + private ErpProductService productService;
  55 + @Resource
  56 + private ErpWarehouseService warehouseService;
  57 + @Resource
  58 + private ErpStockRecordService stockRecordService;
  59 +
  60 + @Override
  61 + @Transactional(rollbackFor = Exception.class)
  62 + public Long createStockCheck(ErpStockCheckSaveReqVO createReqVO) {
  63 + // 1.1 校验盘点项的有效性
  64 + List<ErpStockCheckItemDO> stockCheckItems = validateStockCheckItems(createReqVO.getItems());
  65 + // 1.2 生成盘点单号,并校验唯一性
  66 + String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_CHECK_NO_PREFIX);
  67 + if (stockCheckMapper.selectByNo(no) != null) {
  68 + throw exception(STOCK_CHECK_NO_EXISTS);
  69 + }
  70 +
  71 + // 2.1 插入盘点单
  72 + ErpStockCheckDO stockCheck = BeanUtils.toBean(createReqVO, ErpStockCheckDO.class, in -> in
  73 + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
  74 + .setTotalCount(getSumValue(stockCheckItems, ErpStockCheckItemDO::getCount, BigDecimal::add))
  75 + .setTotalPrice(getSumValue(stockCheckItems, ErpStockCheckItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
  76 + stockCheckMapper.insert(stockCheck);
  77 + // 2.2 插入盘点单项
  78 + stockCheckItems.forEach(o -> o.setCheckId(stockCheck.getId()));
  79 + stockCheckItemMapper.insertBatch(stockCheckItems);
  80 + return stockCheck.getId();
  81 + }
  82 +
  83 + @Override
  84 + @Transactional(rollbackFor = Exception.class)
  85 + public void updateStockCheck(ErpStockCheckSaveReqVO updateReqVO) {
  86 + // 1.1 校验存在
  87 + ErpStockCheckDO stockCheck = validateStockCheckExists(updateReqVO.getId());
  88 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockCheck.getStatus())) {
  89 + throw exception(STOCK_CHECK_UPDATE_FAIL_APPROVE, stockCheck.getNo());
  90 + }
  91 + // 1.2 校验盘点项的有效性
  92 + List<ErpStockCheckItemDO> stockCheckItems = validateStockCheckItems(updateReqVO.getItems());
  93 +
  94 + // 2.1 更新盘点单
  95 + ErpStockCheckDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockCheckDO.class, in -> in
  96 + .setTotalCount(getSumValue(stockCheckItems, ErpStockCheckItemDO::getCount, BigDecimal::add))
  97 + .setTotalPrice(getSumValue(stockCheckItems, ErpStockCheckItemDO::getTotalPrice, BigDecimal::add)));
  98 + stockCheckMapper.updateById(updateObj);
  99 + // 2.2 更新盘点单项
  100 + updateStockCheckItemList(updateReqVO.getId(), stockCheckItems);
  101 + }
  102 +
  103 + @Override
  104 + @Transactional(rollbackFor = Exception.class)
  105 + public void updateStockCheckStatus(Long id, Integer status) {
  106 + boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
  107 + // 1.1 校验存在
  108 + ErpStockCheckDO stockCheck = validateStockCheckExists(id);
  109 + // 1.2 校验状态
  110 + if (stockCheck.getStatus().equals(status)) {
  111 + throw exception(approve ? STOCK_CHECK_APPROVE_FAIL : STOCK_CHECK_PROCESS_FAIL);
  112 + }
  113 +
  114 + // 2. 更新状态
  115 + int updateCount = stockCheckMapper.updateByIdAndStatus(id, stockCheck.getStatus(),
  116 + new ErpStockCheckDO().setStatus(status));
  117 + if (updateCount == 0) {
  118 + throw exception(approve ? STOCK_CHECK_APPROVE_FAIL : STOCK_CHECK_PROCESS_FAIL);
  119 + }
  120 +
  121 + // 3. 变更库存
  122 + List<ErpStockCheckItemDO> stockCheckItems = stockCheckItemMapper.selectListByCheckId(id);
  123 + stockCheckItems.forEach(stockCheckItem -> {
  124 + // 没有盈亏,不用出入库
  125 + if (stockCheckItem.getCount().compareTo(BigDecimal.ZERO) == 0) {
  126 + return;
  127 + }
  128 + // 10;12;-2()
  129 + BigDecimal count = approve ? stockCheckItem.getCount(): stockCheckItem.getCount().negate();
  130 + Integer bizType;
  131 + if (approve) {
  132 + bizType = count.compareTo(BigDecimal.ZERO) > 0 ? ErpStockRecordBizTypeEnum.CHECK_MORE_IN.getType()
  133 + : ErpStockRecordBizTypeEnum.CHECK_LESS_OUT.getType();
  134 + } else {
  135 + bizType = count.compareTo(BigDecimal.ZERO) > 0 ? ErpStockRecordBizTypeEnum.CHECK_MORE_IN_CANCEL.getType()
  136 + : ErpStockRecordBizTypeEnum.CHECK_LESS_OUT_CANCEL.getType();
  137 + }
  138 + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
  139 + stockCheckItem.getProductId(), stockCheckItem.getWarehouseId(), count,
  140 + bizType, stockCheckItem.getCheckId(), stockCheckItem.getId(), stockCheck.getNo()));
  141 + });
  142 + }
  143 +
  144 + private List<ErpStockCheckItemDO> validateStockCheckItems(List<ErpStockCheckSaveReqVO.Item> list) {
  145 + // 1.1 校验产品存在
  146 + List<ErpProductDO> productList = productService.validProductList(
  147 + convertSet(list, ErpStockCheckSaveReqVO.Item::getProductId));
  148 + Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
  149 + // 1.2 校验仓库存在
  150 + warehouseService.validWarehouseList(convertSet(list, ErpStockCheckSaveReqVO.Item::getWarehouseId));
  151 + // 2. 转化为 ErpStockCheckItemDO 列表
  152 + return convertList(list, o -> BeanUtils.toBean(o, ErpStockCheckItemDO.class, item -> item
  153 + .setProductUnitId(productMap.get(item.getProductId()).getUnitId())
  154 + .setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()))));
  155 + }
  156 +
  157 + private void updateStockCheckItemList(Long id, List<ErpStockCheckItemDO> newList) {
  158 + // 第一步,对比新老数据,获得添加、修改、删除的列表
  159 + List<ErpStockCheckItemDO> oldList = stockCheckItemMapper.selectListByCheckId(id);
  160 + List<List<ErpStockCheckItemDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
  161 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
  162 +
  163 + // 第二步,批量添加、修改、删除
  164 + if (CollUtil.isNotEmpty(diffList.get(0))) {
  165 + diffList.get(0).forEach(o -> o.setCheckId(id));
  166 + stockCheckItemMapper.insertBatch(diffList.get(0));
  167 + }
  168 + if (CollUtil.isNotEmpty(diffList.get(1))) {
  169 + stockCheckItemMapper.updateBatch(diffList.get(1));
  170 + }
  171 + if (CollUtil.isNotEmpty(diffList.get(2))) {
  172 + stockCheckItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpStockCheckItemDO::getId));
  173 + }
  174 + }
  175 +
  176 + @Override
  177 + @Transactional(rollbackFor = Exception.class)
  178 + public void deleteStockCheck(List<Long> ids) {
  179 + // 1. 校验不处于已审批
  180 + List<ErpStockCheckDO> stockChecks = stockCheckMapper.selectBatchIds(ids);
  181 + if (CollUtil.isEmpty(stockChecks)) {
  182 + return;
  183 + }
  184 + stockChecks.forEach(stockCheck -> {
  185 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockCheck.getStatus())) {
  186 + throw exception(STOCK_CHECK_DELETE_FAIL_APPROVE, stockCheck.getNo());
  187 + }
  188 + });
  189 +
  190 + // 2. 遍历删除,并记录操作日志
  191 + stockChecks.forEach(stockCheck -> {
  192 + // 2.1 删除盘点单
  193 + stockCheckMapper.deleteById(stockCheck.getId());
  194 + // 2.2 删除盘点单项
  195 + stockCheckItemMapper.deleteByCheckId(stockCheck.getId());
  196 + });
  197 + }
  198 +
  199 + private ErpStockCheckDO validateStockCheckExists(Long id) {
  200 + ErpStockCheckDO stockCheck = stockCheckMapper.selectById(id);
  201 + if (stockCheck == null) {
  202 + throw exception(STOCK_CHECK_NOT_EXISTS);
  203 + }
  204 + return stockCheck;
  205 + }
  206 +
  207 + @Override
  208 + public ErpStockCheckDO getStockCheck(Long id) {
  209 + return stockCheckMapper.selectById(id);
  210 + }
  211 +
  212 + @Override
  213 + public PageResult<ErpStockCheckDO> getStockCheckPage(ErpStockCheckPageReqVO pageReqVO) {
  214 + return stockCheckMapper.selectPage(pageReqVO);
  215 + }
  216 +
  217 + // ==================== 盘点项 ====================
  218 +
  219 + @Override
  220 + public List<ErpStockCheckItemDO> getStockCheckItemListByCheckId(Long checkId) {
  221 + return stockCheckItemMapper.selectListByCheckId(checkId);
  222 + }
  223 +
  224 + @Override
  225 + public List<ErpStockCheckItemDO> getStockCheckItemListByCheckIds(Collection<Long> checkIds) {
  226 + if (CollUtil.isEmpty(checkIds)) {
  227 + return Collections.emptyList();
  228 + }
  229 + return stockCheckItemMapper.selectListByCheckIds(checkIds);
  230 + }
  231 +
  232 +}
0 233 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * ERP 其它入库单 Service 接口
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +public interface ErpStockInService {
  19 +
  20 + /**
  21 + * 创建其它入库单
  22 + *
  23 + * @param createReqVO 创建信息
  24 + * @return 编号
  25 + */
  26 + Long createStockIn(@Valid ErpStockInSaveReqVO createReqVO);
  27 +
  28 + /**
  29 + * 更新其它入库单
  30 + *
  31 + * @param updateReqVO 更新信息
  32 + */
  33 + void updateStockIn(@Valid ErpStockInSaveReqVO updateReqVO);
  34 +
  35 + /**
  36 + * 更新其它入库单的状态
  37 + *
  38 + * @param id 编号
  39 + * @param status 状态
  40 + */
  41 + void updateStockInStatus(Long id, Integer status);
  42 +
  43 + /**
  44 + * 删除其它入库单
  45 + *
  46 + * @param ids 编号数组
  47 + */
  48 + void deleteStockIn(List<Long> ids);
  49 +
  50 + /**
  51 + * 获得其它入库单
  52 + *
  53 + * @param id 编号
  54 + * @return 其它入库单
  55 + */
  56 + ErpStockInDO getStockIn(Long id);
  57 +
  58 + /**
  59 + * 获得其它入库单分页
  60 + *
  61 + * @param pageReqVO 分页查询
  62 + * @return 其它入库单分页
  63 + */
  64 + PageResult<ErpStockInDO> getStockInPage(ErpStockInPageReqVO pageReqVO);
  65 +
  66 + // ==================== 入库项 ====================
  67 +
  68 + /**
  69 + * 获得其它入库单项列表
  70 + *
  71 + * @param inId 入库编号
  72 + * @return 其它入库单项列表
  73 + */
  74 + List<ErpStockInItemDO> getStockInItemListByInId(Long inId);
  75 +
  76 + /**
  77 + * 获得其它入库单项 List
  78 + *
  79 + * @param inIds 入库编号数组
  80 + * @return 其它入库单项 List
  81 + */
  82 + List<ErpStockInItemDO> getStockInItemListByInIds(Collection<Long> inIds);
  83 +
  84 +}
0 85 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO;
  8 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO;
  9 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  10 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
  11 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
  12 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper;
  14 +import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
  15 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  16 +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
  17 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  18 +import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
  19 +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
  20 +import jakarta.annotation.Resource;
  21 +import org.springframework.stereotype.Service;
  22 +import org.springframework.transaction.annotation.Transactional;
  23 +import org.springframework.validation.annotation.Validated;
  24 +
  25 +import java.math.BigDecimal;
  26 +import java.util.Collection;
  27 +import java.util.Collections;
  28 +import java.util.List;
  29 +import java.util.Map;
  30 +
  31 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  33 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  34 +
  35 +// TODO 芋艿:记录操作日志
  36 +/**
  37 + * ERP 其它入库单 Service 实现类
  38 + *
  39 + * @author 芋道源码
  40 + */
  41 +@Service
  42 +@Validated
  43 +public class ErpStockInServiceImpl implements ErpStockInService {
  44 +
  45 + @Resource
  46 + private ErpStockInMapper stockInMapper;
  47 + @Resource
  48 + private ErpStockInItemMapper stockInItemMapper;
  49 +
  50 + @Resource
  51 + private ErpNoRedisDAO noRedisDAO;
  52 +
  53 + @Resource
  54 + private ErpProductService productService;
  55 + @Resource
  56 + private ErpWarehouseService warehouseService;
  57 + @Resource
  58 + private ErpSupplierService supplierService;
  59 + @Resource
  60 + private ErpStockRecordService stockRecordService;
  61 +
  62 + @Override
  63 + @Transactional(rollbackFor = Exception.class)
  64 + public Long createStockIn(ErpStockInSaveReqVO createReqVO) {
  65 + // 1.1 校验入库项的有效性
  66 + List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems());
  67 + // 1.2 校验供应商
  68 + supplierService.validateSupplier(createReqVO.getSupplierId());
  69 + // 1.3 生成入库单号,并校验唯一性
  70 + String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_IN_NO_PREFIX);
  71 + if (stockInMapper.selectByNo(no) != null) {
  72 + throw exception(STOCK_IN_NO_EXISTS);
  73 + }
  74 +
  75 + // 2.1 插入入库单
  76 + ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in
  77 + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
  78 + .setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add))
  79 + .setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
  80 + stockInMapper.insert(stockIn);
  81 + // 2.2 插入入库单项
  82 + stockInItems.forEach(o -> o.setInId(stockIn.getId()));
  83 + stockInItemMapper.insertBatch(stockInItems);
  84 + return stockIn.getId();
  85 + }
  86 +
  87 + @Override
  88 + @Transactional(rollbackFor = Exception.class)
  89 + public void updateStockIn(ErpStockInSaveReqVO updateReqVO) {
  90 + // 1.1 校验存在
  91 + ErpStockInDO stockIn = validateStockInExists(updateReqVO.getId());
  92 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) {
  93 + throw exception(STOCK_IN_UPDATE_FAIL_APPROVE, stockIn.getNo());
  94 + }
  95 + // 1.2 校验供应商
  96 + supplierService.validateSupplier(updateReqVO.getSupplierId());
  97 + // 1.3 校验入库项的有效性
  98 + List<ErpStockInItemDO> stockInItems = validateStockInItems(updateReqVO.getItems());
  99 +
  100 + // 2.1 更新入库单
  101 + ErpStockInDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockInDO.class, in -> in
  102 + .setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add))
  103 + .setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add)));
  104 + stockInMapper.updateById(updateObj);
  105 + // 2.2 更新入库单项
  106 + updateStockInItemList(updateReqVO.getId(), stockInItems);
  107 + }
  108 +
  109 + @Override
  110 + @Transactional(rollbackFor = Exception.class)
  111 + public void updateStockInStatus(Long id, Integer status) {
  112 + boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
  113 + // 1.1 校验存在
  114 + ErpStockInDO stockIn = validateStockInExists(id);
  115 + // 1.2 校验状态
  116 + if (stockIn.getStatus().equals(status)) {
  117 + throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL);
  118 + }
  119 +
  120 + // 2. 更新状态
  121 + int updateCount = stockInMapper.updateByIdAndStatus(id, stockIn.getStatus(),
  122 + new ErpStockInDO().setStatus(status));
  123 + if (updateCount == 0) {
  124 + throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL);
  125 + }
  126 +
  127 + // 3. 变更库存
  128 + List<ErpStockInItemDO> stockInItems = stockInItemMapper.selectListByInId(id);
  129 + Integer bizType = approve ? ErpStockRecordBizTypeEnum.OTHER_IN.getType()
  130 + : ErpStockRecordBizTypeEnum.OTHER_IN_CANCEL.getType();
  131 + stockInItems.forEach(stockInItem -> {
  132 + BigDecimal count = approve ? stockInItem.getCount() : stockInItem.getCount().negate();
  133 + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
  134 + stockInItem.getProductId(), stockInItem.getWarehouseId(), count,
  135 + bizType, stockInItem.getInId(), stockInItem.getId(), stockIn.getNo()));
  136 + });
  137 + }
  138 +
  139 + private List<ErpStockInItemDO> validateStockInItems(List<ErpStockInSaveReqVO.Item> list) {
  140 + // 1.1 校验产品存在
  141 + List<ErpProductDO> productList = productService.validProductList(
  142 + convertSet(list, ErpStockInSaveReqVO.Item::getProductId));
  143 + Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
  144 + // 1.2 校验仓库存在
  145 + warehouseService.validWarehouseList(convertSet(
  146 + list, ErpStockInSaveReqVO.Item::getWarehouseId));
  147 + // 2. 转化为 ErpStockInItemDO 列表
  148 + return convertList(list, o -> BeanUtils.toBean(o, ErpStockInItemDO.class, item -> item
  149 + .setProductUnitId(productMap.get(item.getProductId()).getUnitId())
  150 + .setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()))));
  151 + }
  152 +
  153 + private void updateStockInItemList(Long id, List<ErpStockInItemDO> newList) {
  154 + // 第一步,对比新老数据,获得添加、修改、删除的列表
  155 + List<ErpStockInItemDO> oldList = stockInItemMapper.selectListByInId(id);
  156 + List<List<ErpStockInItemDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
  157 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
  158 +
  159 + // 第二步,批量添加、修改、删除
  160 + if (CollUtil.isNotEmpty(diffList.get(0))) {
  161 + diffList.get(0).forEach(o -> o.setInId(id));
  162 + stockInItemMapper.insertBatch(diffList.get(0));
  163 + }
  164 + if (CollUtil.isNotEmpty(diffList.get(1))) {
  165 + stockInItemMapper.updateBatch(diffList.get(1));
  166 + }
  167 + if (CollUtil.isNotEmpty(diffList.get(2))) {
  168 + stockInItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpStockInItemDO::getId));
  169 + }
  170 + }
  171 +
  172 + @Override
  173 + @Transactional(rollbackFor = Exception.class)
  174 + public void deleteStockIn(List<Long> ids) {
  175 + // 1. 校验不处于已审批
  176 + List<ErpStockInDO> stockIns = stockInMapper.selectBatchIds(ids);
  177 + if (CollUtil.isEmpty(stockIns)) {
  178 + return;
  179 + }
  180 + stockIns.forEach(stockIn -> {
  181 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) {
  182 + throw exception(STOCK_IN_DELETE_FAIL_APPROVE, stockIn.getNo());
  183 + }
  184 + });
  185 +
  186 + // 2. 遍历删除,并记录操作日志
  187 + stockIns.forEach(stockIn -> {
  188 + // 2.1 删除入库单
  189 + stockInMapper.deleteById(stockIn.getId());
  190 + // 2.2 删除入库单项
  191 + stockInItemMapper.deleteByInId(stockIn.getId());
  192 + });
  193 + }
  194 +
  195 + private ErpStockInDO validateStockInExists(Long id) {
  196 + ErpStockInDO stockIn = stockInMapper.selectById(id);
  197 + if (stockIn == null) {
  198 + throw exception(STOCK_IN_NOT_EXISTS);
  199 + }
  200 + return stockIn;
  201 + }
  202 +
  203 + @Override
  204 + public ErpStockInDO getStockIn(Long id) {
  205 + return stockInMapper.selectById(id);
  206 + }
  207 +
  208 + @Override
  209 + public PageResult<ErpStockInDO> getStockInPage(ErpStockInPageReqVO pageReqVO) {
  210 + return stockInMapper.selectPage(pageReqVO);
  211 + }
  212 +
  213 + // ==================== 入库项 ====================
  214 +
  215 + @Override
  216 + public List<ErpStockInItemDO> getStockInItemListByInId(Long inId) {
  217 + return stockInItemMapper.selectListByInId(inId);
  218 + }
  219 +
  220 + @Override
  221 + public List<ErpStockInItemDO> getStockInItemListByInIds(Collection<Long> inIds) {
  222 + if (CollUtil.isEmpty(inIds)) {
  223 + return Collections.emptyList();
  224 + }
  225 + return stockInItemMapper.selectListByInIds(inIds);
  226 + }
  227 +
  228 +}
0 229 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * ERP 库存调拨单 Service 接口
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +public interface ErpStockMoveService {
  19 +
  20 + /**
  21 + * 创建库存调拨单
  22 + *
  23 + * @param createReqVO 创建信息
  24 + * @return 编号
  25 + */
  26 + Long createStockMove(@Valid ErpStockMoveSaveReqVO createReqVO);
  27 +
  28 + /**
  29 + * 更新库存调拨单
  30 + *
  31 + * @param updateReqVO 更新信息
  32 + */
  33 + void updateStockMove(@Valid ErpStockMoveSaveReqVO updateReqVO);
  34 +
  35 + /**
  36 + * 更新库存调拨单的状态
  37 + *
  38 + * @param id 编号
  39 + * @param status 状态
  40 + */
  41 + void updateStockMoveStatus(Long id, Integer status);
  42 +
  43 + /**
  44 + * 删除库存调拨单
  45 + *
  46 + * @param ids 编号数组
  47 + */
  48 + void deleteStockMove(List<Long> ids);
  49 +
  50 + /**
  51 + * 获得库存调拨单
  52 + *
  53 + * @param id 编号
  54 + * @return 库存调拨单
  55 + */
  56 + ErpStockMoveDO getStockMove(Long id);
  57 +
  58 + /**
  59 + * 获得库存调拨单分页
  60 + *
  61 + * @param pageReqVO 分页查询
  62 + * @return 库存调拨单分页
  63 + */
  64 + PageResult<ErpStockMoveDO> getStockMovePage(ErpStockMovePageReqVO pageReqVO);
  65 +
  66 + // ==================== 调拨项 ====================
  67 +
  68 + /**
  69 + * 获得库存调拨单项列表
  70 + *
  71 + * @param moveId 调拨编号
  72 + * @return 库存调拨单项列表
  73 + */
  74 + List<ErpStockMoveItemDO> getStockMoveItemListByMoveId(Long moveId);
  75 +
  76 + /**
  77 + * 获得库存调拨单项 List
  78 + *
  79 + * @param moveIds 调拨编号数组
  80 + * @return 库存调拨单项 List
  81 + */
  82 + List<ErpStockMoveItemDO> getStockMoveItemListByMoveIds(Collection<Long> moveIds);
  83 +
  84 +}
0 85 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO;
  8 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO;
  9 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  10 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO;
  11 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO;
  12 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMoveItemMapper;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMoveMapper;
  14 +import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
  15 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  16 +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
  17 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  18 +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
  19 +import jakarta.annotation.Resource;
  20 +import org.springframework.stereotype.Service;
  21 +import org.springframework.transaction.annotation.Transactional;
  22 +import org.springframework.validation.annotation.Validated;
  23 +
  24 +import java.math.BigDecimal;
  25 +import java.util.Collection;
  26 +import java.util.Collections;
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +import java.util.stream.Stream;
  30 +
  31 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  33 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  34 +
  35 +// TODO 芋艿:记录操作日志
  36 +
  37 +/**
  38 + * ERP 库存调拨单 Service 实现类
  39 + *
  40 + * @author 芋道源码
  41 + */
  42 +@Service
  43 +@Validated
  44 +public class ErpStockMoveServiceImpl implements ErpStockMoveService {
  45 +
  46 + @Resource
  47 + private ErpStockMoveMapper stockMoveMapper;
  48 + @Resource
  49 + private ErpStockMoveItemMapper stockMoveItemMapper;
  50 +
  51 + @Resource
  52 + private ErpNoRedisDAO noRedisDAO;
  53 +
  54 + @Resource
  55 + private ErpProductService productService;
  56 + @Resource
  57 + private ErpWarehouseService warehouseService;
  58 + @Resource
  59 + private ErpStockRecordService stockRecordService;
  60 +
  61 + @Override
  62 + @Transactional(rollbackFor = Exception.class)
  63 + public Long createStockMove(ErpStockMoveSaveReqVO createReqVO) {
  64 + // 1.1 校验出库项的有效性
  65 + List<ErpStockMoveItemDO> stockMoveItems = validateStockMoveItems(createReqVO.getItems());
  66 + // 1.2 生成调拨单号,并校验唯一性
  67 + String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_MOVE_NO_PREFIX);
  68 + if (stockMoveMapper.selectByNo(no) != null) {
  69 + throw exception(STOCK_MOVE_NO_EXISTS);
  70 + }
  71 +
  72 + // 2.1 插入出库单
  73 + ErpStockMoveDO stockMove = BeanUtils.toBean(createReqVO, ErpStockMoveDO.class, in -> in
  74 + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
  75 + .setTotalCount(getSumValue(stockMoveItems, ErpStockMoveItemDO::getCount, BigDecimal::add))
  76 + .setTotalPrice(getSumValue(stockMoveItems, ErpStockMoveItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
  77 + stockMoveMapper.insert(stockMove);
  78 + // 2.2 插入出库单项
  79 + stockMoveItems.forEach(o -> o.setMoveId(stockMove.getId()));
  80 + stockMoveItemMapper.insertBatch(stockMoveItems);
  81 + return stockMove.getId();
  82 + }
  83 +
  84 + @Override
  85 + @Transactional(rollbackFor = Exception.class)
  86 + public void updateStockMove(ErpStockMoveSaveReqVO updateReqVO) {
  87 + // 1.1 校验存在
  88 + ErpStockMoveDO stockMove = validateStockMoveExists(updateReqVO.getId());
  89 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) {
  90 + throw exception(STOCK_MOVE_UPDATE_FAIL_APPROVE, stockMove.getNo());
  91 + }
  92 + // 1.2 校验出库项的有效性
  93 + List<ErpStockMoveItemDO> stockMoveItems = validateStockMoveItems(updateReqVO.getItems());
  94 +
  95 + // 2.1 更新出库单
  96 + ErpStockMoveDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockMoveDO.class, in -> in
  97 + .setTotalCount(getSumValue(stockMoveItems, ErpStockMoveItemDO::getCount, BigDecimal::add))
  98 + .setTotalPrice(getSumValue(stockMoveItems, ErpStockMoveItemDO::getTotalPrice, BigDecimal::add)));
  99 + stockMoveMapper.updateById(updateObj);
  100 + // 2.2 更新出库单项
  101 + updateStockMoveItemList(updateReqVO.getId(), stockMoveItems);
  102 + }
  103 +
  104 + @Override
  105 + @Transactional(rollbackFor = Exception.class)
  106 + public void updateStockMoveStatus(Long id, Integer status) {
  107 + boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
  108 + // 1.1 校验存在
  109 + ErpStockMoveDO stockMove = validateStockMoveExists(id);
  110 + // 1.2 校验状态
  111 + if (stockMove.getStatus().equals(status)) {
  112 + throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL);
  113 + }
  114 +
  115 + // 2. 更新状态
  116 + int updateCount = stockMoveMapper.updateByIdAndStatus(id, stockMove.getStatus(),
  117 + new ErpStockMoveDO().setStatus(status));
  118 + if (updateCount == 0) {
  119 + throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL);
  120 + }
  121 +
  122 + // 3. 变更库存
  123 + List<ErpStockMoveItemDO> stockMoveItems = stockMoveItemMapper.selectListByMoveId(id);
  124 + Integer fromBizType = approve ? ErpStockRecordBizTypeEnum.MOVE_OUT.getType()
  125 + : ErpStockRecordBizTypeEnum.MOVE_OUT_CANCEL.getType();
  126 + Integer toBizType = approve ? ErpStockRecordBizTypeEnum.MOVE_IN.getType()
  127 + : ErpStockRecordBizTypeEnum.MOVE_IN_CANCEL.getType();
  128 + stockMoveItems.forEach(stockMoveItem -> {
  129 + BigDecimal fromCount = approve ? stockMoveItem.getCount().negate() : stockMoveItem.getCount();
  130 + BigDecimal toCount = approve ? stockMoveItem.getCount() : stockMoveItem.getCount().negate();
  131 + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
  132 + stockMoveItem.getProductId(), stockMoveItem.getFromWarehouseId(), fromCount,
  133 + fromBizType, stockMoveItem.getMoveId(), stockMoveItem.getId(), stockMove.getNo()));
  134 + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
  135 + stockMoveItem.getProductId(), stockMoveItem.getToWarehouseId(), toCount,
  136 + toBizType, stockMoveItem.getMoveId(), stockMoveItem.getId(), stockMove.getNo()));
  137 + });
  138 + }
  139 +
  140 + private List<ErpStockMoveItemDO> validateStockMoveItems(List<ErpStockMoveSaveReqVO.Item> list) {
  141 + // 1.1 校验产品存在
  142 + List<ErpProductDO> productList = productService.validProductList(
  143 + convertSet(list, ErpStockMoveSaveReqVO.Item::getProductId));
  144 + Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
  145 + // 1.2 校验仓库存在
  146 + warehouseService.validWarehouseList(convertSetByFlatMap(list,
  147 + item -> Stream.of(item.getFromWarehouseId(), item.getToWarehouseId())));
  148 + // 2. 转化为 ErpStockMoveItemDO 列表
  149 + return convertList(list, o -> BeanUtils.toBean(o, ErpStockMoveItemDO.class, item -> item
  150 + .setProductUnitId(productMap.get(item.getProductId()).getUnitId())
  151 + .setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()))));
  152 + }
  153 +
  154 + private void updateStockMoveItemList(Long id, List<ErpStockMoveItemDO> newList) {
  155 + // 第一步,对比新老数据,获得添加、修改、删除的列表
  156 + List<ErpStockMoveItemDO> oldList = stockMoveItemMapper.selectListByMoveId(id);
  157 + List<List<ErpStockMoveItemDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
  158 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
  159 +
  160 + // 第二步,批量添加、修改、删除
  161 + if (CollUtil.isNotEmpty(diffList.get(0))) {
  162 + diffList.get(0).forEach(o -> o.setMoveId(id));
  163 + stockMoveItemMapper.insertBatch(diffList.get(0));
  164 + }
  165 + if (CollUtil.isNotEmpty(diffList.get(1))) {
  166 + stockMoveItemMapper.updateBatch(diffList.get(1));
  167 + }
  168 + if (CollUtil.isNotEmpty(diffList.get(2))) {
  169 + stockMoveItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpStockMoveItemDO::getId));
  170 + }
  171 + }
  172 +
  173 + @Override
  174 + @Transactional(rollbackFor = Exception.class)
  175 + public void deleteStockMove(List<Long> ids) {
  176 + // 1. 校验不处于已审批
  177 + List<ErpStockMoveDO> stockMoves = stockMoveMapper.selectBatchIds(ids);
  178 + if (CollUtil.isEmpty(stockMoves)) {
  179 + return;
  180 + }
  181 + stockMoves.forEach(stockMove -> {
  182 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) {
  183 + throw exception(STOCK_MOVE_DELETE_FAIL_APPROVE, stockMove.getNo());
  184 + }
  185 + });
  186 +
  187 + // 2. 遍历删除,并记录操作日志
  188 + stockMoves.forEach(stockMove -> {
  189 + // 2.1 删除出库单
  190 + stockMoveMapper.deleteById(stockMove.getId());
  191 + // 2.2 删除出库单项
  192 + stockMoveItemMapper.deleteByMoveId(stockMove.getId());
  193 + });
  194 + }
  195 +
  196 + private ErpStockMoveDO validateStockMoveExists(Long id) {
  197 + ErpStockMoveDO stockMove = stockMoveMapper.selectById(id);
  198 + if (stockMove == null) {
  199 + throw exception(STOCK_MOVE_NOT_EXISTS);
  200 + }
  201 + return stockMove;
  202 + }
  203 +
  204 + @Override
  205 + public ErpStockMoveDO getStockMove(Long id) {
  206 + return stockMoveMapper.selectById(id);
  207 + }
  208 +
  209 + @Override
  210 + public PageResult<ErpStockMoveDO> getStockMovePage(ErpStockMovePageReqVO pageReqVO) {
  211 + return stockMoveMapper.selectPage(pageReqVO);
  212 + }
  213 +
  214 + // ==================== 出库项 ====================
  215 +
  216 + @Override
  217 + public List<ErpStockMoveItemDO> getStockMoveItemListByMoveId(Long moveId) {
  218 + return stockMoveItemMapper.selectListByMoveId(moveId);
  219 + }
  220 +
  221 + @Override
  222 + public List<ErpStockMoveItemDO> getStockMoveItemListByMoveIds(Collection<Long> moveIds) {
  223 + if (CollUtil.isEmpty(moveIds)) {
  224 + return Collections.emptyList();
  225 + }
  226 + return stockMoveItemMapper.selectListByMoveIds(moveIds);
  227 + }
  228 +
  229 +}
0 230 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * ERP 其它出库单 Service 接口
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +public interface ErpStockOutService {
  19 +
  20 + /**
  21 + * 创建其它出库单
  22 + *
  23 + * @param createReqVO 创建信息
  24 + * @return 编号
  25 + */
  26 + Long createStockOut(@Valid ErpStockOutSaveReqVO createReqVO);
  27 +
  28 + /**
  29 + * 更新其它出库单
  30 + *
  31 + * @param updateReqVO 更新信息
  32 + */
  33 + void updateStockOut(@Valid ErpStockOutSaveReqVO updateReqVO);
  34 +
  35 + /**
  36 + * 更新其它出库单的状态
  37 + *
  38 + * @param id 编号
  39 + * @param status 状态
  40 + */
  41 + void updateStockOutStatus(Long id, Integer status);
  42 +
  43 + /**
  44 + * 删除其它出库单
  45 + *
  46 + * @param ids 编号数组
  47 + */
  48 + void deleteStockOut(List<Long> ids);
  49 +
  50 + /**
  51 + * 获得其它出库单
  52 + *
  53 + * @param id 编号
  54 + * @return 其它出库单
  55 + */
  56 + ErpStockOutDO getStockOut(Long id);
  57 +
  58 + /**
  59 + * 获得其它出库单分页
  60 + *
  61 + * @param pageReqVO 分页查询
  62 + * @return 其它出库单分页
  63 + */
  64 + PageResult<ErpStockOutDO> getStockOutPage(ErpStockOutPageReqVO pageReqVO);
  65 +
  66 + // ==================== 出库项 ====================
  67 +
  68 + /**
  69 + * 获得其它出库单项列表
  70 + *
  71 + * @param outId 出库编号
  72 + * @return 其它出库单项列表
  73 + */
  74 + List<ErpStockOutItemDO> getStockOutItemListByOutId(Long outId);
  75 +
  76 + /**
  77 + * 获得其它出库单项 List
  78 + *
  79 + * @param outIds 出库编号数组
  80 + * @return 其它出库单项 List
  81 + */
  82 + List<ErpStockOutItemDO> getStockOutItemListByOutIds(Collection<Long> outIds);
  83 +
  84 +}
0 85 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO;
  8 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
  9 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  10 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
  11 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
  12 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutItemMapper;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutMapper;
  14 +import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
  15 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  16 +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
  17 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  18 +import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
  19 +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
  20 +import jakarta.annotation.Resource;
  21 +import org.springframework.stereotype.Service;
  22 +import org.springframework.transaction.annotation.Transactional;
  23 +import org.springframework.validation.annotation.Validated;
  24 +
  25 +import java.math.BigDecimal;
  26 +import java.util.Collection;
  27 +import java.util.Collections;
  28 +import java.util.List;
  29 +import java.util.Map;
  30 +
  31 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  33 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  34 +
  35 +// TODO 芋艿:记录操作日志
  36 +
  37 +/**
  38 + * ERP 其它出库单 Service 实现类
  39 + *
  40 + * @author 芋道源码
  41 + */
  42 +@Service
  43 +@Validated
  44 +public class ErpStockOutServiceImpl implements ErpStockOutService {
  45 +
  46 + @Resource
  47 + private ErpStockOutMapper stockOutMapper;
  48 + @Resource
  49 + private ErpStockOutItemMapper stockOutItemMapper;
  50 +
  51 + @Resource
  52 + private ErpNoRedisDAO noRedisDAO;
  53 +
  54 + @Resource
  55 + private ErpProductService productService;
  56 + @Resource
  57 + private ErpWarehouseService warehouseService;
  58 + @Resource
  59 + private ErpCustomerService customerService;
  60 + @Resource
  61 + private ErpStockRecordService stockRecordService;
  62 +
  63 + @Override
  64 + @Transactional(rollbackFor = Exception.class)
  65 + public Long createStockOut(ErpStockOutSaveReqVO createReqVO) {
  66 + // 1.1 校验出库项的有效性
  67 + List<ErpStockOutItemDO> stockOutItems = validateStockOutItems(createReqVO.getItems());
  68 + // 1.2 校验客户
  69 + customerService.validateCustomer(createReqVO.getCustomerId());
  70 + // 1.3 生成出库单号,并校验唯一性
  71 + String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_OUT_NO_PREFIX);
  72 + if (stockOutMapper.selectByNo(no) != null) {
  73 + throw exception(STOCK_OUT_NO_EXISTS);
  74 + }
  75 +
  76 + // 2.1 插入出库单
  77 + ErpStockOutDO stockOut = BeanUtils.toBean(createReqVO, ErpStockOutDO.class, in -> in
  78 + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
  79 + .setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
  80 + .setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
  81 + stockOutMapper.insert(stockOut);
  82 + // 2.2 插入出库单项
  83 + stockOutItems.forEach(o -> o.setOutId(stockOut.getId()));
  84 + stockOutItemMapper.insertBatch(stockOutItems);
  85 + return stockOut.getId();
  86 + }
  87 +
  88 + @Override
  89 + @Transactional(rollbackFor = Exception.class)
  90 + public void updateStockOut(ErpStockOutSaveReqVO updateReqVO) {
  91 + // 1.1 校验存在
  92 + ErpStockOutDO stockOut = validateStockOutExists(updateReqVO.getId());
  93 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockOut.getStatus())) {
  94 + throw exception(STOCK_OUT_UPDATE_FAIL_APPROVE, stockOut.getNo());
  95 + }
  96 + // 1.2 校验客户
  97 + customerService.validateCustomer(updateReqVO.getCustomerId());
  98 + // 1.3 校验出库项的有效性
  99 + List<ErpStockOutItemDO> stockOutItems = validateStockOutItems(updateReqVO.getItems());
  100 +
  101 + // 2.1 更新出库单
  102 + ErpStockOutDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockOutDO.class, in -> in
  103 + .setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
  104 + .setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add)));
  105 + stockOutMapper.updateById(updateObj);
  106 + // 2.2 更新出库单项
  107 + updateStockOutItemList(updateReqVO.getId(), stockOutItems);
  108 + }
  109 +
  110 + @Override
  111 + @Transactional(rollbackFor = Exception.class)
  112 + public void updateStockOutStatus(Long id, Integer status) {
  113 + boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
  114 + // 1.1 校验存在
  115 + ErpStockOutDO stockOut = validateStockOutExists(id);
  116 + // 1.2 校验状态
  117 + if (stockOut.getStatus().equals(status)) {
  118 + throw exception(approve ? STOCK_OUT_APPROVE_FAIL : STOCK_OUT_PROCESS_FAIL);
  119 + }
  120 +
  121 + // 2. 更新状态
  122 + int updateCount = stockOutMapper.updateByIdAndStatus(id, stockOut.getStatus(),
  123 + new ErpStockOutDO().setStatus(status));
  124 + if (updateCount == 0) {
  125 + throw exception(approve ? STOCK_OUT_APPROVE_FAIL : STOCK_OUT_PROCESS_FAIL);
  126 + }
  127 +
  128 + // 3. 变更库存
  129 + List<ErpStockOutItemDO> stockOutItems = stockOutItemMapper.selectListByOutId(id);
  130 + Integer bizType = approve ? ErpStockRecordBizTypeEnum.OTHER_OUT.getType()
  131 + : ErpStockRecordBizTypeEnum.OTHER_OUT_CANCEL.getType();
  132 + stockOutItems.forEach(stockOutItem -> {
  133 + BigDecimal count = approve ? stockOutItem.getCount().negate() : stockOutItem.getCount();
  134 + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
  135 + stockOutItem.getProductId(), stockOutItem.getWarehouseId(), count,
  136 + bizType, stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo()));
  137 + });
  138 + }
  139 +
  140 + private List<ErpStockOutItemDO> validateStockOutItems(List<ErpStockOutSaveReqVO.Item> list) {
  141 + // 1.1 校验产品存在
  142 + List<ErpProductDO> productList = productService.validProductList(
  143 + convertSet(list, ErpStockOutSaveReqVO.Item::getProductId));
  144 + Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
  145 + // 1.2 校验仓库存在
  146 + warehouseService.validWarehouseList(convertSet(list, ErpStockOutSaveReqVO.Item::getWarehouseId));
  147 + // 2. 转化为 ErpStockOutItemDO 列表
  148 + return convertList(list, o -> BeanUtils.toBean(o, ErpStockOutItemDO.class, item -> item
  149 + .setProductUnitId(productMap.get(item.getProductId()).getUnitId())
  150 + .setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()))));
  151 + }
  152 +
  153 + private void updateStockOutItemList(Long id, List<ErpStockOutItemDO> newList) {
  154 + // 第一步,对比新老数据,获得添加、修改、删除的列表
  155 + List<ErpStockOutItemDO> oldList = stockOutItemMapper.selectListByOutId(id);
  156 + List<List<ErpStockOutItemDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
  157 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
  158 +
  159 + // 第二步,批量添加、修改、删除
  160 + if (CollUtil.isNotEmpty(diffList.get(0))) {
  161 + diffList.get(0).forEach(o -> o.setOutId(id));
  162 + stockOutItemMapper.insertBatch(diffList.get(0));
  163 + }
  164 + if (CollUtil.isNotEmpty(diffList.get(1))) {
  165 + stockOutItemMapper.updateBatch(diffList.get(1));
  166 + }
  167 + if (CollUtil.isNotEmpty(diffList.get(2))) {
  168 + stockOutItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpStockOutItemDO::getId));
  169 + }
  170 + }
  171 +
  172 + @Override
  173 + @Transactional(rollbackFor = Exception.class)
  174 + public void deleteStockOut(List<Long> ids) {
  175 + // 1. 校验不处于已审批
  176 + List<ErpStockOutDO> stockOuts = stockOutMapper.selectBatchIds(ids);
  177 + if (CollUtil.isEmpty(stockOuts)) {
  178 + return;
  179 + }
  180 + stockOuts.forEach(stockOut -> {
  181 + if (ErpAuditStatus.APPROVE.getStatus().equals(stockOut.getStatus())) {
  182 + throw exception(STOCK_OUT_DELETE_FAIL_APPROVE, stockOut.getNo());
  183 + }
  184 + });
  185 +
  186 + // 2. 遍历删除,并记录操作日志
  187 + stockOuts.forEach(stockOut -> {
  188 + // 2.1 删除出库单
  189 + stockOutMapper.deleteById(stockOut.getId());
  190 + // 2.2 删除出库单项
  191 + stockOutItemMapper.deleteByOutId(stockOut.getId());
  192 + });
  193 + }
  194 +
  195 + private ErpStockOutDO validateStockOutExists(Long id) {
  196 + ErpStockOutDO stockOut = stockOutMapper.selectById(id);
  197 + if (stockOut == null) {
  198 + throw exception(STOCK_OUT_NOT_EXISTS);
  199 + }
  200 + return stockOut;
  201 + }
  202 +
  203 + @Override
  204 + public ErpStockOutDO getStockOut(Long id) {
  205 + return stockOutMapper.selectById(id);
  206 + }
  207 +
  208 + @Override
  209 + public PageResult<ErpStockOutDO> getStockOutPage(ErpStockOutPageReqVO pageReqVO) {
  210 + return stockOutMapper.selectPage(pageReqVO);
  211 + }
  212 +
  213 + // ==================== 出库项 ====================
  214 +
  215 + @Override
  216 + public List<ErpStockOutItemDO> getStockOutItemListByOutId(Long outId) {
  217 + return stockOutItemMapper.selectListByOutId(outId);
  218 + }
  219 +
  220 + @Override
  221 + public List<ErpStockOutItemDO> getStockOutItemListByOutIds(Collection<Long> outIds) {
  222 + if (CollUtil.isEmpty(outIds)) {
  223 + return Collections.emptyList();
  224 + }
  225 + return stockOutItemMapper.selectListByOutIds(outIds);
  226 + }
  227 +
  228 +}
0 229 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockRecordService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
  6 +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +/**
  10 + * ERP 产品库存明细 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface ErpStockRecordService {
  15 +
  16 + /**
  17 + * 获得产品库存明细
  18 + *
  19 + * @param id 编号
  20 + * @return 产品库存明细
  21 + */
  22 + ErpStockRecordDO getStockRecord(Long id);
  23 +
  24 + /**
  25 + * 获得产品库存明细分页
  26 + *
  27 + * @param pageReqVO 分页查询
  28 + * @return 产品库存明细分页
  29 + */
  30 + PageResult<ErpStockRecordDO> getStockRecordPage(ErpStockRecordPageReqVO pageReqVO);
  31 +
  32 + /**
  33 + * 创建库存明细
  34 + *
  35 + * @param createReqBO 创建库存明细 BO
  36 + */
  37 + void createStockRecord(@Valid ErpStockRecordCreateReqBO createReqBO);
  38 +
  39 +}
0 40 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockRecordServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
  7 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockRecordMapper;
  8 +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.stereotype.Service;
  11 +import org.springframework.transaction.annotation.Transactional;
  12 +import org.springframework.validation.annotation.Validated;
  13 +
  14 +import java.math.BigDecimal;
  15 +
  16 +/**
  17 + * ERP 产品库存明细 Service 实现类
  18 + *
  19 + * @author 芋道源码
  20 + */
  21 +@Service
  22 +@Validated
  23 +public class ErpStockRecordServiceImpl implements ErpStockRecordService {
  24 +
  25 + @Resource
  26 + private ErpStockRecordMapper stockRecordMapper;
  27 +
  28 + @Resource
  29 + private ErpStockService stockService;
  30 +
  31 + @Override
  32 + public ErpStockRecordDO getStockRecord(Long id) {
  33 + return stockRecordMapper.selectById(id);
  34 + }
  35 +
  36 + @Override
  37 + public PageResult<ErpStockRecordDO> getStockRecordPage(ErpStockRecordPageReqVO pageReqVO) {
  38 + return stockRecordMapper.selectPage(pageReqVO);
  39 + }
  40 +
  41 + @Override
  42 + @Transactional(rollbackFor = Exception.class)
  43 + public void createStockRecord(ErpStockRecordCreateReqBO createReqBO) {
  44 + // 1. 更新库存
  45 + BigDecimal totalCount = stockService.updateStockCountIncrement(
  46 + createReqBO.getProductId(), createReqBO.getWarehouseId(), createReqBO.getCount());
  47 + // 2. 创建库存明细
  48 + ErpStockRecordDO stockRecord = BeanUtils.toBean(createReqBO, ErpStockRecordDO.class)
  49 + .setTotalCount(totalCount);
  50 + stockRecordMapper.insert(stockRecord);
  51 + }
  52 +
  53 +}
0 54 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
  6 +
  7 +import java.math.BigDecimal;
  8 +
  9 +/**
  10 + * ERP 产品库存 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface ErpStockService {
  15 +
  16 + /**
  17 + * 获得产品库存
  18 + *
  19 + * @param id 编号
  20 + * @return 库存
  21 + */
  22 + ErpStockDO getStock(Long id);
  23 +
  24 + /**
  25 + * 基于产品 + 仓库,获得产品库存
  26 + *
  27 + * @param productId 产品编号
  28 + * @param warehouseId 仓库编号
  29 + * @return 产品库存
  30 + */
  31 + ErpStockDO getStock(Long productId, Long warehouseId);
  32 +
  33 + /**
  34 + * 获得产品库存分页
  35 + *
  36 + * @param pageReqVO 分页查询
  37 + * @return 库存分页
  38 + */
  39 + PageResult<ErpStockDO> getStockPage(ErpStockPageReqVO pageReqVO);
  40 +
  41 + /**
  42 + * 增量更新产品库存数量
  43 + *
  44 + * @param productId 产品编号
  45 + * @param warehouseId 仓库编号
  46 + * @param count 增量数量:正数,表示增加;负数,表示减少
  47 + * @return 更新后的库存
  48 + */
  49 + BigDecimal updateStockCountIncrement(Long productId, Long warehouseId, BigDecimal count);
  50 +
  51 +}
0 52 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
  6 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
  7 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  8 +import jakarta.annotation.Resource;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import java.math.BigDecimal;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  15 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_COUNT_NEGATIVE;
  16 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_COUNT_NEGATIVE2;
  17 +
  18 +/**
  19 + * ERP 产品库存 Service 实现类
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@Service
  24 +@Validated
  25 +public class ErpStockServiceImpl implements ErpStockService {
  26 +
  27 + /**
  28 + * 允许库存为负数
  29 + *
  30 + * TODO 芋艿:后续做成 db 配置
  31 + */
  32 + private static final Boolean NEGATIVE_STOCK_COUNT_ENABLE = false;
  33 +
  34 + @Resource
  35 + private ErpProductService productService;
  36 + @Resource
  37 + private ErpWarehouseService warehouseService;
  38 +
  39 + @Resource
  40 + private ErpStockMapper stockMapper;
  41 +
  42 + @Override
  43 + public ErpStockDO getStock(Long id) {
  44 + return stockMapper.selectById(id);
  45 + }
  46 +
  47 + @Override
  48 + public ErpStockDO getStock(Long productId, Long warehouseId) {
  49 + return stockMapper.selectByProductIdAndWarehouseId(productId, warehouseId);
  50 + }
  51 +
  52 + @Override
  53 + public PageResult<ErpStockDO> getStockPage(ErpStockPageReqVO pageReqVO) {
  54 + return stockMapper.selectPage(pageReqVO);
  55 + }
  56 +
  57 + @Override
  58 + public BigDecimal updateStockCountIncrement(Long productId, Long warehouseId, BigDecimal count) {
  59 + // 1.1 查询当前库存
  60 + ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseId(productId, warehouseId);
  61 + if (stock == null) {
  62 + stock = new ErpStockDO().setProductId(productId).setWarehouseId(warehouseId).setCount(BigDecimal.ZERO);
  63 + stockMapper.insert(stock);
  64 + }
  65 + // 1.2 校验库存是否充足
  66 + if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) {
  67 + throw exception(STOCK_COUNT_NEGATIVE, productService.getProduct(productId).getName(),
  68 + warehouseService.getWarehouse(warehouseId).getName(), stock.getCount(), count);
  69 + }
  70 +
  71 + // 2. 库存变更
  72 + int updateCount = stockMapper.updateCountIncrement(stock.getId(), count, NEGATIVE_STOCK_COUNT_ENABLE);
  73 + if (updateCount == 0) {
  74 + // 此时不好去查询最新库存,所以直接抛出该提示,不提供具体库存数字
  75 + throw exception(STOCK_COUNT_NEGATIVE2, productService.getProduct(productId).getName(),
  76 + warehouseService.getWarehouse(warehouseId).getName());
  77 + }
  78 +
  79 + // 3. 返回最新库存
  80 + return stock.getCount().add(count);
  81 + }
  82 +
  83 +}
0 84 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpWarehouseService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.ErpWarehouseSaveReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  14 +
  15 +/**
  16 + * ERP 仓库 Service 接口
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +public interface ErpWarehouseService {
  21 +
  22 + /**
  23 + * 创建仓库
  24 + *
  25 + * @param createReqVO 创建信息
  26 + * @return 编号
  27 + */
  28 + Long createWarehouse(@Valid ErpWarehouseSaveReqVO createReqVO);
  29 +
  30 + /**
  31 + * 更新ERP 仓库
  32 + *
  33 + * @param updateReqVO 更新信息
  34 + */
  35 + void updateWarehouse(@Valid ErpWarehouseSaveReqVO updateReqVO);
  36 +
  37 + /**
  38 + * 更新仓库默认状态
  39 + *
  40 + * @param id 编号
  41 + * @param defaultStatus 默认状态
  42 + */
  43 + void updateWarehouseDefaultStatus(Long id, Boolean defaultStatus);
  44 +
  45 + /**
  46 + * 删除仓库
  47 + *
  48 + * @param id 编号
  49 + */
  50 + void deleteWarehouse(Long id);
  51 +
  52 + /**
  53 + * 获得仓库
  54 + *
  55 + * @param id 编号
  56 + * @return 仓库
  57 + */
  58 + ErpWarehouseDO getWarehouse(Long id);
  59 +
  60 + /**
  61 + * 校验仓库列表的有效性
  62 + *
  63 + * @param ids 编号数组
  64 + * @return 仓库列表
  65 + */
  66 + List<ErpWarehouseDO> validWarehouseList(Collection<Long> ids);
  67 +
  68 + /**
  69 + * 获得指定状态的仓库列表
  70 + *
  71 + * @param status 状态
  72 + * @return 仓库列表
  73 + */
  74 + List<ErpWarehouseDO> getWarehouseListByStatus(Integer status);
  75 +
  76 + /**
  77 + * 获得仓库列表
  78 + *
  79 + * @param ids 编号数组
  80 + * @return 仓库列表
  81 + */
  82 + List<ErpWarehouseDO> getWarehouseList(Collection<Long> ids);
  83 +
  84 + /**
  85 + * 获得仓库 Map
  86 + *
  87 + * @param ids 编号数组
  88 + * @return 仓库 Map
  89 + */
  90 + default Map<Long, ErpWarehouseDO> getWarehouseMap(Collection<Long> ids) {
  91 + return convertMap(getWarehouseList(ids), ErpWarehouseDO::getId);
  92 + }
  93 +
  94 + /**
  95 + * 获得仓库分页
  96 + *
  97 + * @param pageReqVO 分页查询
  98 + * @return 仓库分页
  99 + */
  100 + PageResult<ErpWarehouseDO> getWarehousePage(ErpWarehousePageReqVO pageReqVO);
  101 +
  102 +}
0 103 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpWarehouseServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.ErpWarehouseSaveReqVO;
  8 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
  9 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  10 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
  11 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpWarehouseMapper;
  12 +import jakarta.annotation.Resource;
  13 +import org.springframework.stereotype.Service;
  14 +import org.springframework.transaction.annotation.Transactional;
  15 +import org.springframework.validation.annotation.Validated;
  16 +
  17 +import java.util.Collection;
  18 +import java.util.Collections;
  19 +import java.util.List;
  20 +import java.util.Map;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  23 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  24 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  25 +
  26 +/**
  27 + * ERP 仓库 Service 实现类
  28 + *
  29 + * @author 芋道源码
  30 + */
  31 +@Service
  32 +@Validated
  33 +public class ErpWarehouseServiceImpl implements ErpWarehouseService {
  34 +
  35 + @Resource
  36 + private ErpWarehouseMapper warehouseMapper;
  37 +
  38 + @Override
  39 + public Long createWarehouse(ErpWarehouseSaveReqVO createReqVO) {
  40 + // 插入
  41 + ErpWarehouseDO warehouse = BeanUtils.toBean(createReqVO, ErpWarehouseDO.class);
  42 + warehouseMapper.insert(warehouse);
  43 + // 返回
  44 + return warehouse.getId();
  45 + }
  46 +
  47 + @Override
  48 + public void updateWarehouse(ErpWarehouseSaveReqVO updateReqVO) {
  49 + // 校验存在
  50 + validateWarehouseExists(updateReqVO.getId());
  51 + // 更新
  52 + ErpWarehouseDO updateObj = BeanUtils.toBean(updateReqVO, ErpWarehouseDO.class);
  53 + warehouseMapper.updateById(updateObj);
  54 + }
  55 +
  56 + @Override
  57 + @Transactional(rollbackFor = Exception.class)
  58 + public void updateWarehouseDefaultStatus(Long id, Boolean defaultStatus) {
  59 + // 1. 校验存在
  60 + validateWarehouseExists(id);
  61 +
  62 + // 2.1 如果开启,则需要关闭所有其它的默认
  63 + if (defaultStatus) {
  64 + ErpWarehouseDO warehouse = warehouseMapper.selectByDefaultStatus();
  65 + if (warehouse != null) {
  66 + warehouseMapper.updateById(new ErpWarehouseDO().setId(warehouse.getId()).setDefaultStatus(false));
  67 + }
  68 + }
  69 + // 2.2 更新对应的默认状态
  70 + warehouseMapper.updateById(new ErpWarehouseDO().setId(id).setDefaultStatus(defaultStatus));
  71 + }
  72 +
  73 + @Override
  74 + public void deleteWarehouse(Long id) {
  75 + // 校验存在
  76 + validateWarehouseExists(id);
  77 + // 删除
  78 + warehouseMapper.deleteById(id);
  79 + }
  80 +
  81 + private void validateWarehouseExists(Long id) {
  82 + if (warehouseMapper.selectById(id) == null) {
  83 + throw exception(WAREHOUSE_NOT_EXISTS);
  84 + }
  85 + }
  86 +
  87 + @Override
  88 + public ErpWarehouseDO getWarehouse(Long id) {
  89 + return warehouseMapper.selectById(id);
  90 + }
  91 +
  92 + @Override
  93 + public List<ErpWarehouseDO> validWarehouseList(Collection<Long> ids) {
  94 + if (CollUtil.isEmpty(ids)) {
  95 + return Collections.emptyList();
  96 + }
  97 + List<ErpWarehouseDO> list = warehouseMapper.selectBatchIds(ids);
  98 + Map<Long, ErpWarehouseDO> warehouseMap = convertMap(list, ErpWarehouseDO::getId);
  99 + for (Long id : ids) {
  100 + ErpWarehouseDO warehouse = warehouseMap.get(id);
  101 + if (warehouseMap.get(id) == null) {
  102 + throw exception(WAREHOUSE_NOT_EXISTS);
  103 + }
  104 + if (CommonStatusEnum.isDisable(warehouse.getStatus())) {
  105 + throw exception(WAREHOUSE_NOT_ENABLE, warehouse.getName());
  106 + }
  107 + }
  108 + return list;
  109 + }
  110 +
  111 + @Override
  112 + public List<ErpWarehouseDO> getWarehouseListByStatus(Integer status) {
  113 + return warehouseMapper.selectListByStatus(status);
  114 + }
  115 +
  116 + @Override
  117 + public List<ErpWarehouseDO> getWarehouseList(Collection<Long> ids) {
  118 + return warehouseMapper.selectBatchIds(ids);
  119 + }
  120 +
  121 + @Override
  122 + public PageResult<ErpWarehouseDO> getWarehousePage(ErpWarehousePageReqVO pageReqVO) {
  123 + return warehouseMapper.selectPage(pageReqVO);
  124 + }
  125 +
  126 +}
0 127 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/bo/ErpStockRecordCreateReqBO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock.bo;
  2 +
  3 +import jakarta.validation.constraints.NotNull;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Data;
  6 +import lombok.NoArgsConstructor;
  7 +
  8 +import java.math.BigDecimal;
  9 +
  10 +/**
  11 + * 库存明细的创建 Request BO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Data
  16 +@NoArgsConstructor
  17 +@AllArgsConstructor
  18 +public class ErpStockRecordCreateReqBO {
  19 +
  20 + /**
  21 + * 产品编号
  22 + */
  23 + @NotNull(message = "产品编号不能为空")
  24 + private Long productId;
  25 + /**
  26 + * 仓库编号
  27 + */
  28 + @NotNull(message = "仓库编号不能为空")
  29 + private Long warehouseId;
  30 + /**
  31 + * 出入库数量
  32 + *
  33 + * 正数,表示入库;负数,表示出库
  34 + */
  35 + @NotNull(message = "出入库数量不能为空")
  36 + private BigDecimal count;
  37 +
  38 + /**
  39 + * 业务类型
  40 + */
  41 + @NotNull(message = "业务类型不能为空")
  42 + private Integer bizType;
  43 + /**
  44 + * 业务编号
  45 + */
  46 + @NotNull(message = "业务编号不能为空")
  47 + private Long bizId;
  48 + /**
  49 + * 业务项编号
  50 + */
  51 + @NotNull(message = "业务项编号不能为空")
  52 + private Long bizItemId;
  53 + /**
  54 + * 业务单号
  55 + */
  56 + @NotNull(message = "业务单号不能为空")
  57 + private String bizNo;
  58 +
  59 +}
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/sale/ErpCustomerMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpCustomerMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
0 13 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/stock/ErpWarehouseMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpWarehouseMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
0 13 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/supplier/ErpSupplierMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpSupplierMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
0 13 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ProductServiceImplTest.java
1 1 package cn.iocoder.yudao.module.erp.service.product;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5   -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPageReqVO;
  3 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
6 4 import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO;
7   -import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
8   -import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
9   -import jakarta.annotation.Resource;
10 5 import org.junit.jupiter.api.Disabled;
11 6 import org.junit.jupiter.api.Test;
  7 +
  8 +import jakarta.annotation.Resource;
  9 +
  10 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  11 +
  12 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
  14 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  15 +
12 16 import org.springframework.context.annotation.Import;
13 17  
14   -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
15   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
16   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
17   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
18   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
19   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
20   -import static cn.iocoder.yudao.module.erp.ErrorCodeConstants.PRODUCT_NOT_EXISTS;
  18 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
  19 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  20 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
  21 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
21 22 import static org.junit.jupiter.api.Assertions.*;
22 23  
23 24 /**
... ... @@ -114,13 +115,13 @@ public class ProductServiceImplTest extends BaseDbUnitTest {
114 115 // 测试 createTime 不匹配
115 116 productMapper.insert(cloneIgnoreId(dbProduct, o -> o.setCreateTime(null)));
116 117 // 准备参数
117   - ProductPageReqVO reqVO = new ProductPageReqVO();
  118 + ErpProductPageReqVO reqVO = new ErpProductPageReqVO();
118 119 reqVO.setName(null);
119 120 reqVO.setCategoryId(null);
120 121 reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
121 122  
122 123 // 调用
123   - PageResult<ErpProductDO> pageResult = productService.getProductPage(reqVO);
  124 + PageResult<ErpProductDO> pageResult = productService.getProductVOPage(reqVO);
124 125 // 断言
125 126 assertEquals(1, pageResult.getTotal());
126 127 assertEquals(1, pageResult.getList().size());
... ...
yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.sale;
  2 +
  3 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO;
  5 +import org.junit.jupiter.api.Disabled;
  6 +import org.junit.jupiter.api.Test;
  7 +
  8 +import jakarta.annotation.Resource;
  9 +
  10 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  11 +
  12 +import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpCustomerMapper;
  14 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  15 +
  16 +import org.springframework.context.annotation.Import;
  17 +
  18 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  19 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
  20 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  21 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
  22 +import static org.junit.jupiter.api.Assertions.*;
  23 +
  24 +/**
  25 + * {@link ErpCustomerServiceImpl} 的单元测试类
  26 + *
  27 + * @author 芋道源码
  28 + */
  29 +@Import(ErpCustomerServiceImpl.class)
  30 +public class ErpCustomerServiceImplTest extends BaseDbUnitTest {
  31 +
  32 + @Resource
  33 + private ErpCustomerServiceImpl customerService;
  34 +
  35 + @Resource
  36 + private ErpCustomerMapper customerMapper;
  37 +
  38 + @Test
  39 + public void testCreateCustomer_success() {
  40 + // 准备参数
  41 + ErpCustomerSaveReqVO createReqVO = randomPojo(ErpCustomerSaveReqVO.class).setId(null);
  42 +
  43 + // 调用
  44 + Long customerId = customerService.createCustomer(createReqVO);
  45 + // 断言
  46 + assertNotNull(customerId);
  47 + // 校验记录的属性是否正确
  48 + ErpCustomerDO customer = customerMapper.selectById(customerId);
  49 + assertPojoEquals(createReqVO, customer, "id");
  50 + }
  51 +
  52 + @Test
  53 + public void testUpdateCustomer_success() {
  54 + // mock 数据
  55 + ErpCustomerDO dbCustomer = randomPojo(ErpCustomerDO.class);
  56 + customerMapper.insert(dbCustomer);// @Sql: 先插入出一条存在的数据
  57 + // 准备参数
  58 + ErpCustomerSaveReqVO updateReqVO = randomPojo(ErpCustomerSaveReqVO.class, o -> {
  59 + o.setId(dbCustomer.getId()); // 设置更新的 ID
  60 + });
  61 +
  62 + // 调用
  63 + customerService.updateCustomer(updateReqVO);
  64 + // 校验是否更新正确
  65 + ErpCustomerDO customer = customerMapper.selectById(updateReqVO.getId()); // 获取最新的
  66 + assertPojoEquals(updateReqVO, customer);
  67 + }
  68 +
  69 + @Test
  70 + public void testUpdateCustomer_notExists() {
  71 + // 准备参数
  72 + ErpCustomerSaveReqVO updateReqVO = randomPojo(ErpCustomerSaveReqVO.class);
  73 +
  74 + // 调用, 并断言异常
  75 + assertServiceException(() -> customerService.updateCustomer(updateReqVO), CUSTOMER_NOT_EXISTS);
  76 + }
  77 +
  78 + @Test
  79 + public void testDeleteCustomer_success() {
  80 + // mock 数据
  81 + ErpCustomerDO dbCustomer = randomPojo(ErpCustomerDO.class);
  82 + customerMapper.insert(dbCustomer);// @Sql: 先插入出一条存在的数据
  83 + // 准备参数
  84 + Long id = dbCustomer.getId();
  85 +
  86 + // 调用
  87 + customerService.deleteCustomer(id);
  88 + // 校验数据不存在了
  89 + assertNull(customerMapper.selectById(id));
  90 + }
  91 +
  92 + @Test
  93 + public void testDeleteCustomer_notExists() {
  94 + // 准备参数
  95 + Long id = randomLongId();
  96 +
  97 + // 调用, 并断言异常
  98 + assertServiceException(() -> customerService.deleteCustomer(id), CUSTOMER_NOT_EXISTS);
  99 + }
  100 +
  101 + @Test
  102 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  103 + public void testGetCustomerPage() {
  104 + // mock 数据
  105 + ErpCustomerDO dbCustomer = randomPojo(ErpCustomerDO.class, o -> { // 等会查询到
  106 + o.setName(null);
  107 + o.setMobile(null);
  108 + o.setTelephone(null);
  109 + });
  110 + customerMapper.insert(dbCustomer);
  111 + // 测试 name 不匹配
  112 + customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setName(null)));
  113 + // 测试 mobile 不匹配
  114 + customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setMobile(null)));
  115 + // 测试 telephone 不匹配
  116 + customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setTelephone(null)));
  117 + // 准备参数
  118 + ErpCustomerPageReqVO reqVO = new ErpCustomerPageReqVO();
  119 + reqVO.setName(null);
  120 + reqVO.setMobile(null);
  121 + reqVO.setTelephone(null);
  122 +
  123 + // 调用
  124 + PageResult<ErpCustomerDO> pageResult = customerService.getCustomerPage(reqVO);
  125 + // 断言
  126 + assertEquals(1, pageResult.getTotal());
  127 + assertEquals(1, pageResult.getList().size());
  128 + assertPojoEquals(dbCustomer, pageResult.getList().get(0));
  129 + }
  130 +
  131 +}
0 132 \ No newline at end of file
... ...
yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/stock/ErpWarehouseServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.stock;
  2 +
  3 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseSaveReqVO;
  5 +import org.junit.jupiter.api.Disabled;
  6 +import org.junit.jupiter.api.Test;
  7 +
  8 +import jakarta.annotation.Resource;
  9 +
  10 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  11 +
  12 +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpWarehouseMapper;
  14 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  15 +
  16 +import org.springframework.context.annotation.Import;
  17 +
  18 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
  19 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  20 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
  21 +import static org.junit.jupiter.api.Assertions.*;
  22 +
  23 +/**
  24 + * {@link ErpWarehouseServiceImpl} 的单元测试类
  25 + *
  26 + * @author 芋道源码
  27 + */
  28 +@Import(ErpWarehouseServiceImpl.class)
  29 +public class ErpWarehouseServiceImplTest extends BaseDbUnitTest {
  30 +
  31 + @Resource
  32 + private ErpWarehouseServiceImpl warehouseService;
  33 +
  34 + @Resource
  35 + private ErpWarehouseMapper warehouseMapper;
  36 +
  37 + @Test
  38 + public void testCreateWarehouse_success() {
  39 + // 准备参数
  40 + ErpWarehouseSaveReqVO createReqVO = randomPojo(ErpWarehouseSaveReqVO.class).setId(null);
  41 +
  42 + // 调用
  43 + Long warehouseId = warehouseService.createWarehouse(createReqVO);
  44 + // 断言
  45 + assertNotNull(warehouseId);
  46 + // 校验记录的属性是否正确
  47 + ErpWarehouseDO warehouse = warehouseMapper.selectById(warehouseId);
  48 + assertPojoEquals(createReqVO, warehouse, "id");
  49 + }
  50 +
  51 + @Test
  52 + public void testUpdateWarehouse_success() {
  53 + // mock 数据
  54 + ErpWarehouseDO dbWarehouse = randomPojo(ErpWarehouseDO.class);
  55 + warehouseMapper.insert(dbWarehouse);// @Sql: 先插入出一条存在的数据
  56 + // 准备参数
  57 + ErpWarehouseSaveReqVO updateReqVO = randomPojo(ErpWarehouseSaveReqVO.class, o -> {
  58 + o.setId(dbWarehouse.getId()); // 设置更新的 ID
  59 + });
  60 +
  61 + // 调用
  62 + warehouseService.updateWarehouse(updateReqVO);
  63 + // 校验是否更新正确
  64 + ErpWarehouseDO warehouse = warehouseMapper.selectById(updateReqVO.getId()); // 获取最新的
  65 + assertPojoEquals(updateReqVO, warehouse);
  66 + }
  67 +
  68 + @Test
  69 + public void testUpdateWarehouse_notExists() {
  70 + // 准备参数
  71 + ErpWarehouseSaveReqVO updateReqVO = randomPojo(ErpWarehouseSaveReqVO.class);
  72 +
  73 + // 调用, 并断言异常
  74 + assertServiceException(() -> warehouseService.updateWarehouse(updateReqVO), WAREHOUSE_NOT_EXISTS);
  75 + }
  76 +
  77 + @Test
  78 + public void testDeleteWarehouse_success() {
  79 + // mock 数据
  80 + ErpWarehouseDO dbWarehouse = randomPojo(ErpWarehouseDO.class);
  81 + warehouseMapper.insert(dbWarehouse);// @Sql: 先插入出一条存在的数据
  82 + // 准备参数
  83 + Long id = dbWarehouse.getId();
  84 +
  85 + // 调用
  86 + warehouseService.deleteWarehouse(id);
  87 + // 校验数据不存在了
  88 + assertNull(warehouseMapper.selectById(id));
  89 + }
  90 +
  91 + @Test
  92 + public void testDeleteWarehouse_notExists() {
  93 + // 准备参数
  94 + Long id = randomLongId();
  95 +
  96 + // 调用, 并断言异常
  97 + assertServiceException(() -> warehouseService.deleteWarehouse(id), WAREHOUSE_NOT_EXISTS);
  98 + }
  99 +
  100 + @Test
  101 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  102 + public void testGetWarehousePage() {
  103 + // mock 数据
  104 + ErpWarehouseDO dbWarehouse = randomPojo(ErpWarehouseDO.class, o -> { // 等会查询到
  105 + o.setName(null);
  106 + o.setStatus(null);
  107 + });
  108 + warehouseMapper.insert(dbWarehouse);
  109 + // 测试 name 不匹配
  110 + warehouseMapper.insert(cloneIgnoreId(dbWarehouse, o -> o.setName(null)));
  111 + // 测试 status 不匹配
  112 + warehouseMapper.insert(cloneIgnoreId(dbWarehouse, o -> o.setStatus(null)));
  113 + // 准备参数
  114 + ErpWarehousePageReqVO reqVO = new ErpWarehousePageReqVO();
  115 + reqVO.setName(null);
  116 + reqVO.setStatus(null);
  117 +
  118 + // 调用
  119 + PageResult<ErpWarehouseDO> pageResult = warehouseService.getWarehousePage(reqVO);
  120 + // 断言
  121 + assertEquals(1, pageResult.getTotal());
  122 + assertEquals(1, pageResult.getList().size());
  123 + assertPojoEquals(dbWarehouse, pageResult.getList().get(0));
  124 + }
  125 +
  126 +}
0 127 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm
... ... @@ -5,13 +5,12 @@ import request from &#39;@/config/axios&#39;
5 5 export interface ${simpleClassName}VO {
6 6 #foreach ($column in $columns)
7 7 #if ($column.createOperation || $column.updateOperation)
8   - // ${column.columnComment}
9 8 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
10   - ${column.javaField}: number
  9 + ${column.javaField}: number // ${column.columnComment}
11 10 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
12   - ${column.javaField}: Date
  11 + ${column.javaField}: Date // ${column.columnComment}
13 12 #else
14   - ${column.javaField}: ${column.javaType.toLowerCase()}
  13 + ${column.javaField}: ${column.javaType.toLowerCase()} // ${column.columnComment}
15 14 #end
16 15 #end
17 16 #end
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/form.vue.vm
... ... @@ -244,7 +244,7 @@ const submitForm = async () =&gt; {
244 244 // 提交请求
245 245 formLoading.value = true
246 246 try {
247   - const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO
  247 + const data = formData.value as unknown as ${simpleClassName}VO
248 248 ## 特殊:主子表专属逻辑
249 249 #if ( $table.templateType == 10 || $table.templateType == 12 )
250 250 #if ( $subTables && $subTables.size() > 0 )
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
... ... @@ -259,8 +259,7 @@ const loading = ref(true) // 列表的加载中
259 259 const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
260 260 ## 特殊:树表专属逻辑(树不需要分页接口)
261 261 #if ( $table.templateType != 2 )
262   -// 列表的总页数
263   -const total = ref(0)
  262 +const total = ref(0) // 列表的总页数
264 263 #end
265 264 const queryParams = reactive({
266 265 ## 特殊:树表专属逻辑(树不需要分页接口)
... ...
yudao-server/src/main/resources/application-local.yaml
... ... @@ -188,6 +188,7 @@ logging:
188 188 cn.iocoder.yudao.module.promotion.dal.mysql: debug
189 189 cn.iocoder.yudao.module.statistics.dal.mysql: debug
190 190 cn.iocoder.yudao.module.crm.dal.mysql: debug
  191 + cn.iocoder.yudao.module.erp.dal.mysql: debug
191 192 org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示
192 193  
193 194 debug: false
... ...