Commit 9ff3593ffb732396da7730950b6cef587a54f34c
1 parent
02fe48e4
feat(wms):增加 code 字段生成(从后端到前端),用户更可控
Showing
18 changed files
with
219 additions
and
54 deletions
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; |
| 12 | 12 | @ToString(callSuper = true) |
| 13 | 13 | public class WmsItemBrandPageReqVO extends PageParam { |
| 14 | 14 | |
| 15 | + @Schema(description = "品牌编号", example = "B00000001") | |
| 16 | + private String code; | |
| 17 | + | |
| 15 | 18 | @Schema(description = "品牌名称", example = "华为") |
| 16 | 19 | private String name; |
| 17 | 20 | ... | ... |
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 { |
| 16 | 16 | @ExcelProperty("编号") |
| 17 | 17 | private Long id; |
| 18 | 18 | |
| 19 | + @Schema(description = "品牌编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "B00000001") | |
| 20 | + @ExcelProperty("品牌编号") | |
| 21 | + private String code; | |
| 22 | + | |
| 19 | 23 | @Schema(description = "品牌名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "华为") |
| 20 | 24 | @ExcelProperty("品牌名称") |
| 21 | 25 | private String name; | ... | ... |
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 { |
| 12 | 12 | @Schema(description = "编号", example = "1024") |
| 13 | 13 | private Long id; |
| 14 | 14 | |
| 15 | + @Schema(description = "品牌编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "B00000001") | |
| 16 | + @NotEmpty(message = "品牌编号不能为空") | |
| 17 | + @Size(max = 20, message = "品牌编号长度不能超过 20 个字符") | |
| 18 | + private String code; | |
| 19 | + | |
| 15 | 20 | @Schema(description = "品牌名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "华为") |
| 16 | 21 | @NotEmpty(message = "品牌名称不能为空") |
| 17 | 22 | @Size(max = 30, message = "品牌名称长度不能超过 30 个字符") | ... | ... |
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 { |
| 12 | 12 | @Schema(description = "父级编号", example = "1") |
| 13 | 13 | private Long parentId; |
| 14 | 14 | |
| 15 | + @Schema(description = "分类编号", example = "C00000001") | |
| 16 | + private String code; | |
| 17 | + | |
| 15 | 18 | @Schema(description = "分类名称", example = "原料") |
| 16 | 19 | private String name; |
| 17 | 20 | ... | ... |
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 { |
| 15 | 15 | @Schema(description = "父级编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| 16 | 16 | private Long parentId; |
| 17 | 17 | |
| 18 | + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "C00000001") | |
| 19 | + private String code; | |
| 20 | + | |
| 18 | 21 | @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "原料") |
| 19 | 22 | private String name; |
| 20 | 23 | ... | ... |
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 { |
| 19 | 19 | @NotNull(message = "父级编号不能为空") |
| 20 | 20 | private Long parentId; |
| 21 | 21 | |
| 22 | + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "C00000001") | |
| 23 | + @NotEmpty(message = "分类编号不能为空") | |
| 24 | + @Size(max = 20, message = "分类编号长度不能超过 20 个字符") | |
| 25 | + private String code; | |
| 26 | + | |
| 22 | 27 | @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "原料") |
| 23 | 28 | @NotEmpty(message = "分类名称不能为空") |
| 24 | 29 | @Size(max = 30, message = "分类名称长度不能超过 30 个字符") | ... | ... |
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 { |
| 18 | 18 | @Schema(description = "编号", example = "1024") |
| 19 | 19 | private Long id; |
| 20 | 20 | |
| 21 | - @Schema(description = "商品编号", example = "ITEM001") | |
| 21 | + @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "ITEM001") | |
| 22 | + @NotBlank(message = "商品编号不能为空") | |
| 22 | 23 | @Size(max = 20, message = "商品编号长度不能超过 20 个字符") |
| 23 | 24 | private String code; |
| 24 | 25 | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemBrandDO.java
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/md/item/WmsItemCategoryDO.java
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<WmsItemBrandDO> { |
| 17 | 17 | |
| 18 | 18 | default PageResult<WmsItemBrandDO> selectPage(WmsItemBrandPageReqVO reqVO) { |
| 19 | 19 | return selectPage(reqVO, new LambdaQueryWrapperX<WmsItemBrandDO>() |
| 20 | + .likeIfPresent(WmsItemBrandDO::getCode, reqVO.getCode()) | |
| 20 | 21 | .likeIfPresent(WmsItemBrandDO::getName, reqVO.getName()) |
| 21 | 22 | .orderByDesc(WmsItemBrandDO::getId)); |
| 22 | 23 | } |
| 23 | 24 | |
| 25 | + default WmsItemBrandDO selectByCode(String code) { | |
| 26 | + return selectOne(WmsItemBrandDO::getCode, code); | |
| 27 | + } | |
| 28 | + | |
| 24 | 29 | } | ... | ... |
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<WmsItemCategoryDO> { |
| 20 | 20 | default List<WmsItemCategoryDO> selectList(WmsItemCategoryListReqVO reqVO) { |
| 21 | 21 | return selectList(new LambdaQueryWrapperX<WmsItemCategoryDO>() |
| 22 | 22 | .eqIfPresent(WmsItemCategoryDO::getParentId, reqVO.getParentId()) |
| 23 | + .likeIfPresent(WmsItemCategoryDO::getCode, reqVO.getCode()) | |
| 23 | 24 | .likeIfPresent(WmsItemCategoryDO::getName, reqVO.getName()) |
| 24 | 25 | .eqIfPresent(WmsItemCategoryDO::getStatus, reqVO.getStatus()) |
| 25 | 26 | .orderByAsc(WmsItemCategoryDO::getSort) |
| ... | ... | @@ -30,6 +31,10 @@ public interface WmsItemCategoryMapper extends BaseMapperX<WmsItemCategoryDO> { |
| 30 | 31 | return selectOne(WmsItemCategoryDO::getParentId, parentId, WmsItemCategoryDO::getName, name); |
| 31 | 32 | } |
| 32 | 33 | |
| 34 | + default WmsItemCategoryDO selectByCode(String code) { | |
| 35 | + return selectOne(WmsItemCategoryDO::getCode, code); | |
| 36 | + } | |
| 37 | + | |
| 33 | 38 | default List<WmsItemCategoryDO> selectListByParentIds(Collection<Long> parentIds) { |
| 34 | 39 | return selectList(new LambdaQueryWrapperX<WmsItemCategoryDO>() |
| 35 | 40 | .in(WmsItemCategoryDO::getParentId, parentIds) | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/md/item/WmsItemBrandServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.wms.service.md.item; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.util.ObjectUtil; | |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | 7 | import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.brand.WmsItemBrandPageReqVO; |
| ... | ... | @@ -16,6 +17,7 @@ import java.util.Collections; |
| 16 | 17 | import java.util.List; |
| 17 | 18 | |
| 18 | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 20 | +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.ITEM_BRAND_CODE_DUPLICATE; | |
| 19 | 21 | import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.ITEM_BRAND_HAS_ITEM; |
| 20 | 22 | import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.ITEM_BRAND_NOT_EXISTS; |
| 21 | 23 | |
| ... | ... | @@ -35,6 +37,9 @@ public class WmsItemBrandServiceImpl implements WmsItemBrandService { |
| 35 | 37 | |
| 36 | 38 | @Override |
| 37 | 39 | public Long createItemBrand(WmsItemBrandSaveReqVO createReqVO) { |
| 40 | + // 校验编号唯一 | |
| 41 | + validateBrandCodeUnique(null, createReqVO.getCode()); | |
| 42 | + | |
| 38 | 43 | WmsItemBrandDO brand = BeanUtils.toBean(createReqVO, WmsItemBrandDO.class); |
| 39 | 44 | brandMapper.insert(brand); |
| 40 | 45 | return brand.getId(); |
| ... | ... | @@ -44,12 +49,28 @@ public class WmsItemBrandServiceImpl implements WmsItemBrandService { |
| 44 | 49 | public void updateItemBrand(WmsItemBrandSaveReqVO updateReqVO) { |
| 45 | 50 | // 校验存在 |
| 46 | 51 | validateItemBrandExists(updateReqVO.getId()); |
| 52 | + // 校验编号唯一 | |
| 53 | + validateBrandCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); | |
| 47 | 54 | |
| 48 | 55 | // 更新 |
| 49 | 56 | WmsItemBrandDO updateObj = BeanUtils.toBean(updateReqVO, WmsItemBrandDO.class); |
| 50 | 57 | brandMapper.updateById(updateObj); |
| 51 | 58 | } |
| 52 | 59 | |
| 60 | + private void validateBrandCodeUnique(Long id, String code) { | |
| 61 | + WmsItemBrandDO brand = brandMapper.selectByCode(code); | |
| 62 | + if (brand == null) { | |
| 63 | + return; | |
| 64 | + } | |
| 65 | + // 如果 id 为空,说明新增;和数据库已有 code 重复 | |
| 66 | + if (id == null) { | |
| 67 | + throw exception(ITEM_BRAND_CODE_DUPLICATE); | |
| 68 | + } | |
| 69 | + if (ObjectUtil.notEqual(brand.getId(), id)) { | |
| 70 | + throw exception(ITEM_BRAND_CODE_DUPLICATE); | |
| 71 | + } | |
| 72 | + } | |
| 73 | + | |
| 53 | 74 | @Override |
| 54 | 75 | public void deleteItemBrand(Long id) { |
| 55 | 76 | // 校验存在 | ... | ... |
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 { |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | private void validateCategorySaveData(WmsItemCategorySaveReqVO reqVO) { |
| 63 | + validateCategoryCodeUnique(reqVO.getId(), reqVO.getCode()); | |
| 63 | 64 | validateCategoryNameUnique(reqVO.getId(), reqVO.getParentId(), reqVO.getName()); |
| 64 | 65 | validateParentCategory(reqVO.getId(), reqVO.getParentId()); |
| 65 | 66 | } |
| 66 | 67 | |
| 68 | + private void validateCategoryCodeUnique(Long id, String code) { | |
| 69 | + WmsItemCategoryDO category = categoryMapper.selectByCode(code); | |
| 70 | + if (category == null) { | |
| 71 | + return; | |
| 72 | + } | |
| 73 | + // 如果 id 为空,说明新增;和数据库已有 code 重复 | |
| 74 | + if (id == null) { | |
| 75 | + throw exception(ITEM_CATEGORY_CODE_DUPLICATE); | |
| 76 | + } | |
| 77 | + if (ObjectUtil.notEqual(category.getId(), id)) { | |
| 78 | + throw exception(ITEM_CATEGORY_CODE_DUPLICATE); | |
| 79 | + } | |
| 80 | + } | |
| 81 | + | |
| 67 | 82 | private void validateCategoryNameUnique(Long id, Long parentId, String name) { |
| 68 | 83 | WmsItemCategoryDO category = categoryMapper.selectByParentIdAndName(parentId, name); |
| 69 | 84 | if (category == null) { | ... | ... |
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; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.collection.ListUtil; |
| 5 | -import cn.hutool.core.util.StrUtil; | |
| 6 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 6 | import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.sku.WmsItemSkuSaveReqVO; |
| 8 | 7 | 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 |
| 13 | 12 | import cn.iocoder.yudao.module.wms.service.order.movement.WmsMovementOrderDetailService; |
| 14 | 13 | import cn.iocoder.yudao.module.wms.service.order.receipt.WmsReceiptOrderDetailService; |
| 15 | 14 | import cn.iocoder.yudao.module.wms.service.order.shipment.WmsShipmentOrderDetailService; |
| 16 | -import cn.iocoder.yudao.module.wms.util.WmsUtils; | |
| 17 | 15 | import jakarta.annotation.Resource; |
| 18 | 16 | import org.springframework.context.annotation.Lazy; |
| 19 | 17 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -64,7 +62,6 @@ public class WmsItemSkuServiceImpl implements WmsItemSkuService { |
| 64 | 62 | if (CollUtil.isNotEmpty(convertList(list, WmsItemSkuDO::getId))) { |
| 65 | 63 | throw exception(ITEM_SKU_NOT_EXISTS); |
| 66 | 64 | } |
| 67 | - fillEmptyBarCode(list); | |
| 68 | 65 | itemSkuMapper.insertBatch(list); |
| 69 | 66 | } |
| 70 | 67 | |
| ... | ... | @@ -92,12 +89,10 @@ public class WmsItemSkuServiceImpl implements WmsItemSkuService { |
| 92 | 89 | throw exception(ITEM_SKU_NOT_EXISTS); |
| 93 | 90 | } |
| 94 | 91 | diffList.get(0).forEach(sku -> sku.setItemId(itemId)); |
| 95 | - fillEmptyBarCode(diffList.get(0)); | |
| 96 | 92 | itemSkuMapper.insertBatch(diffList.get(0)); |
| 97 | 93 | } |
| 98 | 94 | if (CollUtil.isNotEmpty(diffList.get(1))) { |
| 99 | 95 | diffList.get(1).forEach(sku -> sku.setItemId(itemId)); |
| 100 | - fillEmptyBarCode(diffList.get(1)); | |
| 101 | 96 | itemSkuMapper.updateBatch(diffList.get(1)); |
| 102 | 97 | } |
| 103 | 98 | } |
| ... | ... | @@ -185,17 +180,4 @@ public class WmsItemSkuServiceImpl implements WmsItemSkuService { |
| 185 | 180 | } |
| 186 | 181 | } |
| 187 | 182 | |
| 188 | - /** | |
| 189 | - * 填充空的条形码 | |
| 190 | - * | |
| 191 | - * @param skus 商品 SKU 列表 | |
| 192 | - */ | |
| 193 | - private void fillEmptyBarCode(List<WmsItemSkuDO> skus) { | |
| 194 | - skus.forEach(sku -> { | |
| 195 | - if (StrUtil.isBlank(sku.getBarCode())) { | |
| 196 | - sku.setBarCode(WmsUtils.generateBarCode()); | |
| 197 | - } | |
| 198 | - }); | |
| 199 | - } | |
| 200 | - | |
| 201 | 183 | } | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/util/WmsUtils.java deleted
| 1 | -package cn.iocoder.yudao.module.wms.util; | |
| 2 | - | |
| 3 | -import cn.hutool.core.util.RandomUtil; | |
| 4 | -import lombok.experimental.UtilityClass; | |
| 5 | - | |
| 6 | -/** | |
| 7 | - * WMS 工具类 | |
| 8 | - * | |
| 9 | - * @author 芋道源码 | |
| 10 | - */ | |
| 11 | -@UtilityClass | |
| 12 | -public class WmsUtils { | |
| 13 | - | |
| 14 | - private static final int BAR_CODE_LENGTH = 8; | |
| 15 | - | |
| 16 | - /** | |
| 17 | - * 生成条码 | |
| 18 | - * | |
| 19 | - * @return 条码 | |
| 20 | - */ | |
| 21 | - public String generateBarCode() { | |
| 22 | - return RandomUtil.randomNumbers(BAR_CODE_LENGTH); | |
| 23 | - } | |
| 24 | - | |
| 25 | -} |
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; |
| 10 | 10 | import cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum; |
| 11 | 11 | import cn.iocoder.yudao.module.wms.enums.order.WmsOrderStatusEnum; |
| 12 | 12 | import cn.iocoder.yudao.module.wms.service.inventory.WmsInventoryService; |
| 13 | -import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO; | |
| 13 | +import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryCheckReqDTO; | |
| 14 | 14 | import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; |
| 15 | 15 | import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService; |
| 16 | 16 | import jakarta.annotation.Resource; |
| ... | ... | @@ -25,13 +25,16 @@ import java.util.Arrays; |
| 25 | 25 | import java.util.List; |
| 26 | 26 | |
| 27 | 27 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| 28 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 28 | 29 | import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_DETAIL_REQUIRED; |
| 30 | +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_INVENTORY_CHANGED; | |
| 29 | 31 | import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_DELETABLE; |
| 30 | 32 | import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_PREPARE; |
| 31 | 33 | import static org.junit.jupiter.api.Assertions.assertEquals; |
| 32 | 34 | import static org.junit.jupiter.api.Assertions.assertNotNull; |
| 33 | 35 | import static org.junit.jupiter.api.Assertions.assertNull; |
| 34 | 36 | import static org.mockito.ArgumentMatchers.any; |
| 37 | +import static org.mockito.Mockito.doThrow; | |
| 35 | 38 | import static org.mockito.Mockito.never; |
| 36 | 39 | import static org.mockito.Mockito.verify; |
| 37 | 40 | |
| ... | ... | @@ -118,17 +121,19 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { |
| 118 | 121 | WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId()); |
| 119 | 122 | assertNotNull(dbOrder); |
| 120 | 123 | assertEquals(WmsOrderStatusEnum.FINISHED.getStatus(), dbOrder.getStatus()); |
| 121 | - // 断言:库存变更 | |
| 122 | - ArgumentCaptor<WmsInventoryChangeReqDTO> captor = ArgumentCaptor.forClass(WmsInventoryChangeReqDTO.class); | |
| 123 | - verify(inventoryService).changeInventory(captor.capture()); | |
| 124 | - WmsInventoryChangeReqDTO inventoryReqDTO = captor.getValue(); | |
| 124 | + // 断言:库存盘点 | |
| 125 | + ArgumentCaptor<WmsInventoryCheckReqDTO> captor = ArgumentCaptor.forClass(WmsInventoryCheckReqDTO.class); | |
| 126 | + verify(inventoryService).checkInventory(captor.capture()); | |
| 127 | + WmsInventoryCheckReqDTO inventoryReqDTO = captor.getValue(); | |
| 125 | 128 | assertEquals(order.getId(), inventoryReqDTO.getOrderId()); |
| 126 | 129 | assertEquals(order.getNo(), inventoryReqDTO.getOrderNo()); |
| 127 | 130 | assertEquals(WmsOrderTypeEnum.CHECK.getType(), inventoryReqDTO.getOrderType()); |
| 128 | 131 | assertEquals(1, inventoryReqDTO.getItems().size()); |
| 129 | 132 | assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId()); |
| 130 | 133 | assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId()); |
| 131 | - assertEquals(0, new BigDecimal("-3.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); | |
| 134 | + assertEquals(300L, inventoryReqDTO.getItems().get(0).getInventoryId()); | |
| 135 | + assertEquals(0, new BigDecimal("10.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); | |
| 136 | + assertEquals(0, new BigDecimal("7.00").compareTo(inventoryReqDTO.getItems().get(0).getCheckQuantity())); | |
| 132 | 137 | assertEquals(0, new BigDecimal("30.00").compareTo(inventoryReqDTO.getItems().get(0).getPrice())); |
| 133 | 138 | } |
| 134 | 139 | |
| ... | ... | @@ -147,7 +152,49 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { |
| 147 | 152 | WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId()); |
| 148 | 153 | assertNotNull(dbOrder); |
| 149 | 154 | assertEquals(WmsOrderStatusEnum.FINISHED.getStatus(), dbOrder.getStatus()); |
| 150 | - verify(inventoryService, never()).changeInventory(any()); | |
| 155 | + verify(inventoryService).checkInventory(any()); | |
| 156 | + } | |
| 157 | + | |
| 158 | + @Test | |
| 159 | + public void testCompleteCheckOrder_newInventoryCurrentMissing() { | |
| 160 | + // mock 数据 | |
| 161 | + Long warehouseId = 100L; | |
| 162 | + Long skuId = 200L; | |
| 163 | + WmsCheckOrderDO order = createCheckOrder(warehouseId); | |
| 164 | + checkOrderMapper.insert(order); | |
| 165 | + checkOrderDetailMapper.insert(createNewInventoryCheckOrderDetail(order.getId(), skuId, warehouseId, | |
| 166 | + "0.00", "5.00")); | |
| 167 | + // 调用 | |
| 168 | + checkOrderService.completeCheckOrder(order.getId()); | |
| 169 | + | |
| 170 | + // 断言 | |
| 171 | + ArgumentCaptor<WmsInventoryCheckReqDTO> captor = ArgumentCaptor.forClass(WmsInventoryCheckReqDTO.class); | |
| 172 | + verify(inventoryService).checkInventory(captor.capture()); | |
| 173 | + WmsInventoryCheckReqDTO inventoryReqDTO = captor.getValue(); | |
| 174 | + assertEquals(1, inventoryReqDTO.getItems().size()); | |
| 175 | + assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId()); | |
| 176 | + assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId()); | |
| 177 | + assertNull(inventoryReqDTO.getItems().get(0).getInventoryId()); | |
| 178 | + assertEquals(0, new BigDecimal("0.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); | |
| 179 | + assertEquals(0, new BigDecimal("5.00").compareTo(inventoryReqDTO.getItems().get(0).getCheckQuantity())); | |
| 180 | + } | |
| 181 | + | |
| 182 | + @Test | |
| 183 | + public void testCompleteCheckOrder_checkInventoryChanged() { | |
| 184 | + // mock 数据 | |
| 185 | + Long warehouseId = 100L; | |
| 186 | + Long skuId = 200L; | |
| 187 | + WmsCheckOrderDO order = createCheckOrder(warehouseId); | |
| 188 | + checkOrderMapper.insert(order); | |
| 189 | + checkOrderDetailMapper.insert(createNewInventoryCheckOrderDetail(order.getId(), skuId, warehouseId, | |
| 190 | + "0.00", "5.00")); | |
| 191 | + doThrow(exception(CHECK_ORDER_INVENTORY_CHANGED)).when(inventoryService).checkInventory(any()); | |
| 192 | + | |
| 193 | + // 调用,并断言 | |
| 194 | + assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()), | |
| 195 | + CHECK_ORDER_INVENTORY_CHANGED); | |
| 196 | + assertEquals(WmsOrderStatusEnum.PREPARE.getStatus(), | |
| 197 | + checkOrderMapper.selectById(order.getId()).getStatus()); | |
| 151 | 198 | } |
| 152 | 199 | |
| 153 | 200 | @Test |
| ... | ... | @@ -159,7 +206,7 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { |
| 159 | 206 | // 调用,并断言 |
| 160 | 207 | assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()), |
| 161 | 208 | CHECK_ORDER_DETAIL_REQUIRED); |
| 162 | - verify(inventoryService, never()).changeInventory(any()); | |
| 209 | + verify(inventoryService, never()).checkInventory(any()); | |
| 163 | 210 | } |
| 164 | 211 | |
| 165 | 212 | @Test |
| ... | ... | @@ -176,7 +223,7 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { |
| 176 | 223 | // 调用,并断言:二次完成不能再次写库存 |
| 177 | 224 | assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()), |
| 178 | 225 | CHECK_ORDER_STATUS_NOT_PREPARE); |
| 179 | - verify(inventoryService).changeInventory(any()); | |
| 226 | + verify(inventoryService).checkInventory(any()); | |
| 180 | 227 | } |
| 181 | 228 | |
| 182 | 229 | @Test |
| ... | ... | @@ -192,7 +239,7 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { |
| 192 | 239 | WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId()); |
| 193 | 240 | assertNotNull(dbOrder); |
| 194 | 241 | assertEquals(WmsOrderStatusEnum.CANCELED.getStatus(), dbOrder.getStatus()); |
| 195 | - verify(inventoryService, never()).changeInventory(any()); | |
| 242 | + verify(inventoryService, never()).checkInventory(any()); | |
| 196 | 243 | } |
| 197 | 244 | |
| 198 | 245 | @Test |
| ... | ... | @@ -263,6 +310,18 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { |
| 263 | 310 | .build(); |
| 264 | 311 | } |
| 265 | 312 | |
| 313 | + private static WmsCheckOrderDetailDO createNewInventoryCheckOrderDetail(Long orderId, Long skuId, Long warehouseId, | |
| 314 | + String quantity, String checkQuantity) { | |
| 315 | + return WmsCheckOrderDetailDO.builder() | |
| 316 | + .orderId(orderId) | |
| 317 | + .skuId(skuId) | |
| 318 | + .warehouseId(warehouseId) | |
| 319 | + .quantity(new BigDecimal(quantity)) | |
| 320 | + .checkQuantity(new BigDecimal(checkQuantity)) | |
| 321 | + .price(new BigDecimal("30.00")) | |
| 322 | + .build(); | |
| 323 | + } | |
| 324 | + | |
| 266 | 325 | private static WmsCheckOrderSaveReqVO createCheckOrderReqVO(Long warehouseId, WmsCheckOrderDetailSaveReqVO... details) { |
| 267 | 326 | WmsCheckOrderSaveReqVO reqVO = new WmsCheckOrderSaveReqVO(); |
| 268 | 327 | reqVO.setNo("PK202605120002"); | ... | ... |
yudao-module-wms/src/test/resources/sql/clean.sql
| ... | ... | @@ -10,3 +10,7 @@ DELETE FROM "wms_inventory_history"; |
| 10 | 10 | DELETE FROM "wms_inventory"; |
| 11 | 11 | DELETE FROM "wms_item_sku"; |
| 12 | 12 | DELETE FROM "wms_item"; |
| 13 | +DELETE FROM "wms_item_category"; | |
| 14 | +DELETE FROM "wms_item_brand"; | |
| 15 | +DELETE FROM "wms_warehouse"; | |
| 16 | +DELETE FROM "wms_merchant"; | ... | ... |
yudao-module-wms/src/test/resources/sql/create_tables.sql
| 1 | +CREATE TABLE IF NOT EXISTS "wms_warehouse" ( | |
| 2 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 3 | + "code" varchar(20) NOT NULL, | |
| 4 | + "name" varchar(50) NOT NULL, | |
| 5 | + "remark" varchar(255) DEFAULT NULL, | |
| 6 | + "sort" int DEFAULT '0', | |
| 7 | + "creator" varchar(64) DEFAULT '', | |
| 8 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 9 | + "updater" varchar(64) DEFAULT '', | |
| 10 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 11 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 12 | + "tenant_id" bigint NOT NULL DEFAULT '0', | |
| 13 | + PRIMARY KEY ("id") | |
| 14 | +) COMMENT 'WMS 仓库表'; | |
| 15 | + | |
| 16 | +CREATE TABLE IF NOT EXISTS "wms_merchant" ( | |
| 17 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 18 | + "code" varchar(20) DEFAULT NULL, | |
| 19 | + "name" varchar(50) NOT NULL, | |
| 20 | + "type" int NOT NULL, | |
| 21 | + "level" varchar(20) DEFAULT NULL, | |
| 22 | + "bank_name" varchar(50) DEFAULT NULL, | |
| 23 | + "bank_account" varchar(50) DEFAULT NULL, | |
| 24 | + "address" varchar(255) DEFAULT NULL, | |
| 25 | + "mobile" varchar(20) DEFAULT NULL, | |
| 26 | + "telephone" varchar(20) DEFAULT NULL, | |
| 27 | + "contact" varchar(20) DEFAULT NULL, | |
| 28 | + "email" varchar(64) DEFAULT NULL, | |
| 29 | + "remark" varchar(255) DEFAULT NULL, | |
| 30 | + "creator" varchar(64) DEFAULT '', | |
| 31 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 32 | + "updater" varchar(64) DEFAULT '', | |
| 33 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 34 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 35 | + "tenant_id" bigint NOT NULL DEFAULT '0', | |
| 36 | + PRIMARY KEY ("id") | |
| 37 | +) COMMENT 'WMS 往来企业表'; | |
| 38 | + | |
| 39 | +CREATE TABLE IF NOT EXISTS "wms_item_brand" ( | |
| 40 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 41 | + "code" varchar(20) NOT NULL, | |
| 42 | + "name" varchar(60) NOT NULL, | |
| 43 | + "creator" varchar(64) DEFAULT '', | |
| 44 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 45 | + "updater" varchar(64) DEFAULT '', | |
| 46 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 47 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 48 | + "tenant_id" bigint NOT NULL DEFAULT '0', | |
| 49 | + PRIMARY KEY ("id") | |
| 50 | +) COMMENT 'WMS 商品品牌表'; | |
| 51 | + | |
| 52 | +CREATE TABLE IF NOT EXISTS "wms_item_category" ( | |
| 53 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 54 | + "parent_id" bigint NOT NULL DEFAULT '0', | |
| 55 | + "code" varchar(20) NOT NULL, | |
| 56 | + "name" varchar(60) NOT NULL, | |
| 57 | + "sort" int DEFAULT '0', | |
| 58 | + "status" tinyint NOT NULL DEFAULT '0', | |
| 59 | + "creator" varchar(64) DEFAULT '', | |
| 60 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 61 | + "updater" varchar(64) DEFAULT '', | |
| 62 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 63 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 64 | + "tenant_id" bigint NOT NULL DEFAULT '0', | |
| 65 | + PRIMARY KEY ("id") | |
| 66 | +) COMMENT 'WMS 商品分类表'; | |
| 67 | + | |
| 1 | 68 | CREATE TABLE IF NOT EXISTS "wms_item" ( |
| 2 | 69 | "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, |
| 3 | 70 | "code" varchar(20) NOT NULL, | ... | ... |