From 9ff3593ffb732396da7730950b6cef587a54f34c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 15 May 2026 10:22:38 +0800 Subject: [PATCH] feat(wms):增加 code 字段生成(从后端到前端),用户更可控 --- yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandPageReqVO.java | 3 +++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandRespVO.java | 4 ++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandSaveReqVO.java | 5 +++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryListReqVO.java | 3 +++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryRespVO.java | 3 +++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategorySaveReqVO.java | 5 +++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/item/WmsItemSaveReqVO.java | 3 ++- yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemBrandDO.java | 4 ++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemCategoryDO.java | 4 ++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemBrandMapper.java | 5 +++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemCategoryMapper.java | 5 +++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemBrandServiceImpl.java | 21 +++++++++++++++++++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemCategoryServiceImpl.java | 15 +++++++++++++++ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemSkuServiceImpl.java | 18 ------------------ yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/util/WmsUtils.java | 25 ------------------------- yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImplTest.java | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- yudao-module-wms/src/test/resources/sql/clean.sql | 4 ++++ yudao-module-wms/src/test/resources/sql/create_tables.sql | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 18 files changed, 219 insertions(+), 54 deletions(-) delete mode 100644 yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/util/WmsUtils.java diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandPageReqVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandPageReqVO.java index 1946cf4..0e2d745 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandPageReqVO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandPageReqVO.java @@ -12,6 +12,9 @@ import lombok.ToString; @ToString(callSuper = true) public class WmsItemBrandPageReqVO extends PageParam { + @Schema(description = "品牌编号", example = "B00000001") + private String code; + @Schema(description = "品牌名称", example = "华为") private String name; diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandRespVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandRespVO.java index b87a0ed..bc68efe 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandRespVO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandRespVO.java @@ -16,6 +16,10 @@ public class WmsItemBrandRespVO { @ExcelProperty("编号") private Long id; + @Schema(description = "品牌编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "B00000001") + @ExcelProperty("品牌编号") + private String code; + @Schema(description = "品牌名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "华为") @ExcelProperty("品牌名称") private String name; diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandSaveReqVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandSaveReqVO.java index 3112abe..7090cf3 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandSaveReqVO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/brand/WmsItemBrandSaveReqVO.java @@ -12,6 +12,11 @@ public class WmsItemBrandSaveReqVO { @Schema(description = "编号", example = "1024") private Long id; + @Schema(description = "品牌编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "B00000001") + @NotEmpty(message = "品牌编号不能为空") + @Size(max = 20, message = "品牌编号长度不能超过 20 个字符") + private String code; + @Schema(description = "品牌名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "华为") @NotEmpty(message = "品牌名称不能为空") @Size(max = 30, message = "品牌名称长度不能超过 30 个字符") diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryListReqVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryListReqVO.java index 2329aa1..274cad4 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryListReqVO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryListReqVO.java @@ -12,6 +12,9 @@ public class WmsItemCategoryListReqVO { @Schema(description = "父级编号", example = "1") private Long parentId; + @Schema(description = "分类编号", example = "C00000001") + private String code; + @Schema(description = "分类名称", example = "原料") private String name; diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryRespVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryRespVO.java index 593b5f2..d629b98 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryRespVO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategoryRespVO.java @@ -15,6 +15,9 @@ public class WmsItemCategoryRespVO { @Schema(description = "父级编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") private Long parentId; + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "C00000001") + private String code; + @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "原料") private String name; diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategorySaveReqVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategorySaveReqVO.java index a26db9a..8d0df22 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategorySaveReqVO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/category/WmsItemCategorySaveReqVO.java @@ -19,6 +19,11 @@ public class WmsItemCategorySaveReqVO { @NotNull(message = "父级编号不能为空") private Long parentId; + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "C00000001") + @NotEmpty(message = "分类编号不能为空") + @Size(max = 20, message = "分类编号长度不能超过 20 个字符") + private String code; + @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "原料") @NotEmpty(message = "分类名称不能为空") @Size(max = 30, message = "分类名称长度不能超过 30 个字符") diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/item/WmsItemSaveReqVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/item/WmsItemSaveReqVO.java index 02e720f..6b8cadf 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/item/WmsItemSaveReqVO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/item/WmsItemSaveReqVO.java @@ -18,7 +18,8 @@ public class WmsItemSaveReqVO { @Schema(description = "编号", example = "1024") private Long id; - @Schema(description = "商品编号", example = "ITEM001") + @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "ITEM001") + @NotBlank(message = "商品编号不能为空") @Size(max = 20, message = "商品编号长度不能超过 20 个字符") private String code; diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemBrandDO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemBrandDO.java index 996edc4..ab41e05 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemBrandDO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemBrandDO.java @@ -27,6 +27,10 @@ public class WmsItemBrandDO extends BaseDO { @TableId private Long id; /** + * 品牌编号 + */ + private String code; + /** * 品牌名称 */ private String name; diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemCategoryDO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemCategoryDO.java index fdb3a78..ded9228 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemCategoryDO.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemCategoryDO.java @@ -39,6 +39,10 @@ public class WmsItemCategoryDO extends BaseDO { */ private Long parentId; /** + * 分类编号 + */ + private String code; + /** * 分类名称 */ private String name; diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemBrandMapper.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemBrandMapper.java index 4b9bc2d..262539f 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemBrandMapper.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemBrandMapper.java @@ -17,8 +17,13 @@ public interface WmsItemBrandMapper extends BaseMapperX { default PageResult selectPage(WmsItemBrandPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(WmsItemBrandDO::getCode, reqVO.getCode()) .likeIfPresent(WmsItemBrandDO::getName, reqVO.getName()) .orderByDesc(WmsItemBrandDO::getId)); } + default WmsItemBrandDO selectByCode(String code) { + return selectOne(WmsItemBrandDO::getCode, code); + } + } diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemCategoryMapper.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemCategoryMapper.java index 5b95e6e..f95bc30 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemCategoryMapper.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemCategoryMapper.java @@ -20,6 +20,7 @@ public interface WmsItemCategoryMapper extends BaseMapperX { default List selectList(WmsItemCategoryListReqVO reqVO) { return selectList(new LambdaQueryWrapperX() .eqIfPresent(WmsItemCategoryDO::getParentId, reqVO.getParentId()) + .likeIfPresent(WmsItemCategoryDO::getCode, reqVO.getCode()) .likeIfPresent(WmsItemCategoryDO::getName, reqVO.getName()) .eqIfPresent(WmsItemCategoryDO::getStatus, reqVO.getStatus()) .orderByAsc(WmsItemCategoryDO::getSort) @@ -30,6 +31,10 @@ public interface WmsItemCategoryMapper extends BaseMapperX { return selectOne(WmsItemCategoryDO::getParentId, parentId, WmsItemCategoryDO::getName, name); } + default WmsItemCategoryDO selectByCode(String code) { + return selectOne(WmsItemCategoryDO::getCode, code); + } + default List selectListByParentIds(Collection parentIds) { return selectList(new LambdaQueryWrapperX() .in(WmsItemCategoryDO::getParentId, parentIds) diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemBrandServiceImpl.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemBrandServiceImpl.java index 2e30e41..58d8936 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemBrandServiceImpl.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemBrandServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.wms.service.md.item; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.brand.WmsItemBrandPageReqVO; @@ -16,6 +17,7 @@ import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.ITEM_BRAND_CODE_DUPLICATE; import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.ITEM_BRAND_HAS_ITEM; import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.ITEM_BRAND_NOT_EXISTS; @@ -35,6 +37,9 @@ public class WmsItemBrandServiceImpl implements WmsItemBrandService { @Override public Long createItemBrand(WmsItemBrandSaveReqVO createReqVO) { + // 校验编号唯一 + validateBrandCodeUnique(null, createReqVO.getCode()); + WmsItemBrandDO brand = BeanUtils.toBean(createReqVO, WmsItemBrandDO.class); brandMapper.insert(brand); return brand.getId(); @@ -44,12 +49,28 @@ public class WmsItemBrandServiceImpl implements WmsItemBrandService { public void updateItemBrand(WmsItemBrandSaveReqVO updateReqVO) { // 校验存在 validateItemBrandExists(updateReqVO.getId()); + // 校验编号唯一 + validateBrandCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); // 更新 WmsItemBrandDO updateObj = BeanUtils.toBean(updateReqVO, WmsItemBrandDO.class); brandMapper.updateById(updateObj); } + private void validateBrandCodeUnique(Long id, String code) { + WmsItemBrandDO brand = brandMapper.selectByCode(code); + if (brand == null) { + return; + } + // 如果 id 为空,说明新增;和数据库已有 code 重复 + if (id == null) { + throw exception(ITEM_BRAND_CODE_DUPLICATE); + } + if (ObjectUtil.notEqual(brand.getId(), id)) { + throw exception(ITEM_BRAND_CODE_DUPLICATE); + } + } + @Override public void deleteItemBrand(Long id) { // 校验存在 diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemCategoryServiceImpl.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemCategoryServiceImpl.java index f1f1809..0f63fdb 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemCategoryServiceImpl.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemCategoryServiceImpl.java @@ -60,10 +60,25 @@ public class WmsItemCategoryServiceImpl implements WmsItemCategoryService { } private void validateCategorySaveData(WmsItemCategorySaveReqVO reqVO) { + validateCategoryCodeUnique(reqVO.getId(), reqVO.getCode()); validateCategoryNameUnique(reqVO.getId(), reqVO.getParentId(), reqVO.getName()); validateParentCategory(reqVO.getId(), reqVO.getParentId()); } + private void validateCategoryCodeUnique(Long id, String code) { + WmsItemCategoryDO category = categoryMapper.selectByCode(code); + if (category == null) { + return; + } + // 如果 id 为空,说明新增;和数据库已有 code 重复 + if (id == null) { + throw exception(ITEM_CATEGORY_CODE_DUPLICATE); + } + if (ObjectUtil.notEqual(category.getId(), id)) { + throw exception(ITEM_CATEGORY_CODE_DUPLICATE); + } + } + private void validateCategoryNameUnique(Long id, Long parentId, String name) { WmsItemCategoryDO category = categoryMapper.selectByParentIdAndName(parentId, name); if (category == null) { diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemSkuServiceImpl.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemSkuServiceImpl.java index 8a8be71..b89f054 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemSkuServiceImpl.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemSkuServiceImpl.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.wms.service.md.item; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.sku.WmsItemSkuSaveReqVO; import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; @@ -13,7 +12,6 @@ import cn.iocoder.yudao.module.wms.service.order.check.WmsCheckOrderDetailServic import cn.iocoder.yudao.module.wms.service.order.movement.WmsMovementOrderDetailService; import cn.iocoder.yudao.module.wms.service.order.receipt.WmsReceiptOrderDetailService; import cn.iocoder.yudao.module.wms.service.order.shipment.WmsShipmentOrderDetailService; -import cn.iocoder.yudao.module.wms.util.WmsUtils; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -64,7 +62,6 @@ public class WmsItemSkuServiceImpl implements WmsItemSkuService { if (CollUtil.isNotEmpty(convertList(list, WmsItemSkuDO::getId))) { throw exception(ITEM_SKU_NOT_EXISTS); } - fillEmptyBarCode(list); itemSkuMapper.insertBatch(list); } @@ -92,12 +89,10 @@ public class WmsItemSkuServiceImpl implements WmsItemSkuService { throw exception(ITEM_SKU_NOT_EXISTS); } diffList.get(0).forEach(sku -> sku.setItemId(itemId)); - fillEmptyBarCode(diffList.get(0)); itemSkuMapper.insertBatch(diffList.get(0)); } if (CollUtil.isNotEmpty(diffList.get(1))) { diffList.get(1).forEach(sku -> sku.setItemId(itemId)); - fillEmptyBarCode(diffList.get(1)); itemSkuMapper.updateBatch(diffList.get(1)); } } @@ -185,17 +180,4 @@ public class WmsItemSkuServiceImpl implements WmsItemSkuService { } } - /** - * 填充空的条形码 - * - * @param skus 商品 SKU 列表 - */ - private void fillEmptyBarCode(List skus) { - skus.forEach(sku -> { - if (StrUtil.isBlank(sku.getBarCode())) { - sku.setBarCode(WmsUtils.generateBarCode()); - } - }); - } - } diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/util/WmsUtils.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/util/WmsUtils.java deleted file mode 100644 index 917e0cc..0000000 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/util/WmsUtils.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.wms.util; - -import cn.hutool.core.util.RandomUtil; -import lombok.experimental.UtilityClass; - -/** - * WMS 工具类 - * - * @author 芋道源码 - */ -@UtilityClass -public class WmsUtils { - - private static final int BAR_CODE_LENGTH = 8; - - /** - * 生成条码 - * - * @return 条码 - */ - public String generateBarCode() { - return RandomUtil.randomNumbers(BAR_CODE_LENGTH); - } - -} diff --git a/yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImplTest.java b/yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImplTest.java index a49d505..d1233f1 100644 --- a/yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImplTest.java +++ b/yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImplTest.java @@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.wms.dal.mysql.order.check.WmsCheckOrderMapper; import cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum; import cn.iocoder.yudao.module.wms.enums.order.WmsOrderStatusEnum; import cn.iocoder.yudao.module.wms.service.inventory.WmsInventoryService; -import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO; +import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryCheckReqDTO; import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService; import jakarta.annotation.Resource; @@ -25,13 +25,16 @@ import java.util.Arrays; import java.util.List; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_DETAIL_REQUIRED; +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_INVENTORY_CHANGED; import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_DELETABLE; import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_PREPARE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -118,17 +121,19 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId()); assertNotNull(dbOrder); assertEquals(WmsOrderStatusEnum.FINISHED.getStatus(), dbOrder.getStatus()); - // 断言:库存变更 - ArgumentCaptor captor = ArgumentCaptor.forClass(WmsInventoryChangeReqDTO.class); - verify(inventoryService).changeInventory(captor.capture()); - WmsInventoryChangeReqDTO inventoryReqDTO = captor.getValue(); + // 断言:库存盘点 + ArgumentCaptor captor = ArgumentCaptor.forClass(WmsInventoryCheckReqDTO.class); + verify(inventoryService).checkInventory(captor.capture()); + WmsInventoryCheckReqDTO inventoryReqDTO = captor.getValue(); assertEquals(order.getId(), inventoryReqDTO.getOrderId()); assertEquals(order.getNo(), inventoryReqDTO.getOrderNo()); assertEquals(WmsOrderTypeEnum.CHECK.getType(), inventoryReqDTO.getOrderType()); assertEquals(1, inventoryReqDTO.getItems().size()); assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId()); assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId()); - assertEquals(0, new BigDecimal("-3.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); + assertEquals(300L, inventoryReqDTO.getItems().get(0).getInventoryId()); + assertEquals(0, new BigDecimal("10.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); + assertEquals(0, new BigDecimal("7.00").compareTo(inventoryReqDTO.getItems().get(0).getCheckQuantity())); assertEquals(0, new BigDecimal("30.00").compareTo(inventoryReqDTO.getItems().get(0).getPrice())); } @@ -147,7 +152,49 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId()); assertNotNull(dbOrder); assertEquals(WmsOrderStatusEnum.FINISHED.getStatus(), dbOrder.getStatus()); - verify(inventoryService, never()).changeInventory(any()); + verify(inventoryService).checkInventory(any()); + } + + @Test + public void testCompleteCheckOrder_newInventoryCurrentMissing() { + // mock 数据 + Long warehouseId = 100L; + Long skuId = 200L; + WmsCheckOrderDO order = createCheckOrder(warehouseId); + checkOrderMapper.insert(order); + checkOrderDetailMapper.insert(createNewInventoryCheckOrderDetail(order.getId(), skuId, warehouseId, + "0.00", "5.00")); + // 调用 + checkOrderService.completeCheckOrder(order.getId()); + + // 断言 + ArgumentCaptor captor = ArgumentCaptor.forClass(WmsInventoryCheckReqDTO.class); + verify(inventoryService).checkInventory(captor.capture()); + WmsInventoryCheckReqDTO inventoryReqDTO = captor.getValue(); + assertEquals(1, inventoryReqDTO.getItems().size()); + assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId()); + assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId()); + assertNull(inventoryReqDTO.getItems().get(0).getInventoryId()); + assertEquals(0, new BigDecimal("0.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); + assertEquals(0, new BigDecimal("5.00").compareTo(inventoryReqDTO.getItems().get(0).getCheckQuantity())); + } + + @Test + public void testCompleteCheckOrder_checkInventoryChanged() { + // mock 数据 + Long warehouseId = 100L; + Long skuId = 200L; + WmsCheckOrderDO order = createCheckOrder(warehouseId); + checkOrderMapper.insert(order); + checkOrderDetailMapper.insert(createNewInventoryCheckOrderDetail(order.getId(), skuId, warehouseId, + "0.00", "5.00")); + doThrow(exception(CHECK_ORDER_INVENTORY_CHANGED)).when(inventoryService).checkInventory(any()); + + // 调用,并断言 + assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()), + CHECK_ORDER_INVENTORY_CHANGED); + assertEquals(WmsOrderStatusEnum.PREPARE.getStatus(), + checkOrderMapper.selectById(order.getId()).getStatus()); } @Test @@ -159,7 +206,7 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { // 调用,并断言 assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()), CHECK_ORDER_DETAIL_REQUIRED); - verify(inventoryService, never()).changeInventory(any()); + verify(inventoryService, never()).checkInventory(any()); } @Test @@ -176,7 +223,7 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { // 调用,并断言:二次完成不能再次写库存 assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()), CHECK_ORDER_STATUS_NOT_PREPARE); - verify(inventoryService).changeInventory(any()); + verify(inventoryService).checkInventory(any()); } @Test @@ -192,7 +239,7 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId()); assertNotNull(dbOrder); assertEquals(WmsOrderStatusEnum.CANCELED.getStatus(), dbOrder.getStatus()); - verify(inventoryService, never()).changeInventory(any()); + verify(inventoryService, never()).checkInventory(any()); } @Test @@ -263,6 +310,18 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { .build(); } + private static WmsCheckOrderDetailDO createNewInventoryCheckOrderDetail(Long orderId, Long skuId, Long warehouseId, + String quantity, String checkQuantity) { + return WmsCheckOrderDetailDO.builder() + .orderId(orderId) + .skuId(skuId) + .warehouseId(warehouseId) + .quantity(new BigDecimal(quantity)) + .checkQuantity(new BigDecimal(checkQuantity)) + .price(new BigDecimal("30.00")) + .build(); + } + private static WmsCheckOrderSaveReqVO createCheckOrderReqVO(Long warehouseId, WmsCheckOrderDetailSaveReqVO... details) { WmsCheckOrderSaveReqVO reqVO = new WmsCheckOrderSaveReqVO(); reqVO.setNo("PK202605120002"); diff --git a/yudao-module-wms/src/test/resources/sql/clean.sql b/yudao-module-wms/src/test/resources/sql/clean.sql index b636db4..2ca91cb 100644 --- a/yudao-module-wms/src/test/resources/sql/clean.sql +++ b/yudao-module-wms/src/test/resources/sql/clean.sql @@ -10,3 +10,7 @@ DELETE FROM "wms_inventory_history"; DELETE FROM "wms_inventory"; DELETE FROM "wms_item_sku"; DELETE FROM "wms_item"; +DELETE FROM "wms_item_category"; +DELETE FROM "wms_item_brand"; +DELETE FROM "wms_warehouse"; +DELETE FROM "wms_merchant"; diff --git a/yudao-module-wms/src/test/resources/sql/create_tables.sql b/yudao-module-wms/src/test/resources/sql/create_tables.sql index 218a2b7..8742319 100644 --- a/yudao-module-wms/src/test/resources/sql/create_tables.sql +++ b/yudao-module-wms/src/test/resources/sql/create_tables.sql @@ -1,3 +1,70 @@ +CREATE TABLE IF NOT EXISTS "wms_warehouse" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "code" varchar(20) NOT NULL, + "name" varchar(50) NOT NULL, + "remark" varchar(255) DEFAULT NULL, + "sort" int DEFAULT '0', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY ("id") +) COMMENT 'WMS 仓库表'; + +CREATE TABLE IF NOT EXISTS "wms_merchant" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "code" varchar(20) DEFAULT NULL, + "name" varchar(50) NOT NULL, + "type" int NOT NULL, + "level" varchar(20) DEFAULT NULL, + "bank_name" varchar(50) DEFAULT NULL, + "bank_account" varchar(50) DEFAULT NULL, + "address" varchar(255) DEFAULT NULL, + "mobile" varchar(20) DEFAULT NULL, + "telephone" varchar(20) DEFAULT NULL, + "contact" varchar(20) DEFAULT NULL, + "email" varchar(64) DEFAULT NULL, + "remark" varchar(255) DEFAULT NULL, + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY ("id") +) COMMENT 'WMS 往来企业表'; + +CREATE TABLE IF NOT EXISTS "wms_item_brand" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "code" varchar(20) NOT NULL, + "name" varchar(60) NOT NULL, + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY ("id") +) COMMENT 'WMS 商品品牌表'; + +CREATE TABLE IF NOT EXISTS "wms_item_category" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "parent_id" bigint NOT NULL DEFAULT '0', + "code" varchar(20) NOT NULL, + "name" varchar(60) NOT NULL, + "sort" int DEFAULT '0', + "status" tinyint NOT NULL DEFAULT '0', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL DEFAULT '0', + PRIMARY KEY ("id") +) COMMENT 'WMS 商品分类表'; + CREATE TABLE IF NOT EXISTS "wms_item" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "code" varchar(20) NOT NULL, -- libgit2 0.21.4