Commit 32813c08739b86d51c6ee8437caf0d74f8140f4e

Authored by YunaiV
1 parent 77426402

feat(wms):优化入库、出库等订单的完成、取消逻辑,避免并发问题

Showing 13 changed files with 221 additions and 16 deletions
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/check/WmsCheckOrderMapper.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.module.wms.controller.admin.order.check.vo.order.WmsCheckOrderPageReqVO; 6 import cn.iocoder.yudao.module.wms.controller.admin.order.check.vo.order.WmsCheckOrderPageReqVO;
7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.check.WmsCheckOrderDO; 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.check.WmsCheckOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
10 /** 11 /**
@@ -42,4 +43,10 @@ public interface WmsCheckOrderMapper extends BaseMapperX<WmsCheckOrderDO> { @@ -42,4 +43,10 @@ public interface WmsCheckOrderMapper extends BaseMapperX<WmsCheckOrderDO> {
42 return selectCount(WmsCheckOrderDO::getWarehouseId, warehouseId); 43 return selectCount(WmsCheckOrderDO::getWarehouseId, warehouseId);
43 } 44 }
44 45
  46 + default int updateByIdAndStatus(Long id, Integer status, WmsCheckOrderDO updateObj) {
  47 + return update(updateObj, new LambdaQueryWrapper<WmsCheckOrderDO>()
  48 + .eq(WmsCheckOrderDO::getId, id)
  49 + .eq(WmsCheckOrderDO::getStatus, status));
  50 + }
  51 +
45 } 52 }
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/movement/WmsMovementOrderMapper.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderPageReqVO; 6 import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderPageReqVO;
7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDO; 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
10 /** 11 /**
@@ -43,4 +44,10 @@ public interface WmsMovementOrderMapper extends BaseMapperX&lt;WmsMovementOrderDO&gt; @@ -43,4 +44,10 @@ public interface WmsMovementOrderMapper extends BaseMapperX&lt;WmsMovementOrderDO&gt;
43 .or().eq(WmsMovementOrderDO::getTargetWarehouseId, warehouseId))); 44 .or().eq(WmsMovementOrderDO::getTargetWarehouseId, warehouseId)));
44 } 45 }
45 46
  47 + default int updateByIdAndStatus(Long id, Integer status, WmsMovementOrderDO updateObj) {
  48 + return update(updateObj, new LambdaQueryWrapper<WmsMovementOrderDO>()
  49 + .eq(WmsMovementOrderDO::getId, id)
  50 + .eq(WmsMovementOrderDO::getStatus, status));
  51 + }
  52 +
46 } 53 }
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/receipt/WmsReceiptOrderMapper.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderPageReqVO; 6 import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderPageReqVO;
7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO; 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
10 /** 11 /**
@@ -47,4 +48,10 @@ public interface WmsReceiptOrderMapper extends BaseMapperX&lt;WmsReceiptOrderDO&gt; { @@ -47,4 +48,10 @@ public interface WmsReceiptOrderMapper extends BaseMapperX&lt;WmsReceiptOrderDO&gt; {
47 return selectCount(WmsReceiptOrderDO::getWarehouseId, warehouseId); 48 return selectCount(WmsReceiptOrderDO::getWarehouseId, warehouseId);
48 } 49 }
49 50
  51 + default int updateByIdAndStatus(Long id, Integer status, WmsReceiptOrderDO updateObj) {
  52 + return update(updateObj, new LambdaQueryWrapper<WmsReceiptOrderDO>()
  53 + .eq(WmsReceiptOrderDO::getId, id)
  54 + .eq(WmsReceiptOrderDO::getStatus, status));
  55 + }
  56 +
50 } 57 }
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/shipment/WmsShipmentOrderMapper.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.order.WmsShipmentOrderPageReqVO; 6 import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.order.WmsShipmentOrderPageReqVO;
7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment.WmsShipmentOrderDO; 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment.WmsShipmentOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
10 /** 11 /**
@@ -47,4 +48,10 @@ public interface WmsShipmentOrderMapper extends BaseMapperX&lt;WmsShipmentOrderDO&gt; @@ -47,4 +48,10 @@ public interface WmsShipmentOrderMapper extends BaseMapperX&lt;WmsShipmentOrderDO&gt;
47 return selectCount(WmsShipmentOrderDO::getWarehouseId, warehouseId); 48 return selectCount(WmsShipmentOrderDO::getWarehouseId, warehouseId);
48 } 49 }
49 50
  51 + default int updateByIdAndStatus(Long id, Integer status, WmsShipmentOrderDO updateObj) {
  52 + return update(updateObj, new LambdaQueryWrapper<WmsShipmentOrderDO>()
  53 + .eq(WmsShipmentOrderDO::getId, id)
  54 + .eq(WmsShipmentOrderDO::getStatus, status));
  55 + }
  56 +
50 } 57 }
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImpl.java
@@ -102,8 +102,10 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService { @@ -102,8 +102,10 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
102 List<WmsCheckOrderDetailDO> details = checkOrderDetailService.validateCheckOrderDetailListExists(id); 102 List<WmsCheckOrderDetailDO> details = checkOrderDetailService.validateCheckOrderDetailListExists(id);
103 103
104 // 2. 完成盘库单 104 // 2. 完成盘库单
105 - checkOrderMapper.updateById(new WmsCheckOrderDO().setId(id)  
106 - .setStatus(WmsOrderStatusEnum.FINISHED.getStatus())); 105 + if (checkOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  106 + new WmsCheckOrderDO().setStatus(WmsOrderStatusEnum.FINISHED.getStatus())) == 0) {
  107 + throw exception(CHECK_ORDER_STATUS_NOT_PREPARE);
  108 + }
107 109
108 // 3. 盘点库存 110 // 3. 盘点库存
109 changeInventory(order, details); 111 changeInventory(order, details);
@@ -116,8 +118,10 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService { @@ -116,8 +118,10 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
116 validateCheckOrderPrepare(id); 118 validateCheckOrderPrepare(id);
117 119
118 // 2. 作废盘库单 120 // 2. 作废盘库单
119 - checkOrderMapper.updateById(new WmsCheckOrderDO().setId(id)  
120 - .setStatus(WmsOrderStatusEnum.CANCELED.getStatus())); 121 + if (checkOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  122 + new WmsCheckOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus())) == 0) {
  123 + throw exception(CHECK_ORDER_STATUS_NOT_PREPARE);
  124 + }
121 } 125 }
122 126
123 @Override 127 @Override
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderServiceImpl.java
@@ -102,8 +102,10 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService { @@ -102,8 +102,10 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
102 List<WmsMovementOrderDetailDO> details = movementOrderDetailService.validateMovementOrderDetailListExists(id); 102 List<WmsMovementOrderDetailDO> details = movementOrderDetailService.validateMovementOrderDetailListExists(id);
103 103
104 // 2. 完成移库单 104 // 2. 完成移库单
105 - movementOrderMapper.updateById(new WmsMovementOrderDO().setId(id)  
106 - .setStatus(WmsOrderStatusEnum.FINISHED.getStatus())); 105 + if (movementOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  106 + new WmsMovementOrderDO().setStatus(WmsOrderStatusEnum.FINISHED.getStatus())) == 0) {
  107 + throw exception(MOVEMENT_ORDER_STATUS_NOT_PREPARE);
  108 + }
107 109
108 // 3. 移动库存 110 // 3. 移动库存
109 changeInventory(order, details); 111 changeInventory(order, details);
@@ -116,8 +118,10 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService { @@ -116,8 +118,10 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
116 validateMovementOrderPrepare(id); 118 validateMovementOrderPrepare(id);
117 119
118 // 2. 作废移库单 120 // 2. 作废移库单
119 - movementOrderMapper.updateById(new WmsMovementOrderDO().setId(id)  
120 - .setStatus(WmsOrderStatusEnum.CANCELED.getStatus())); 121 + if (movementOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  122 + new WmsMovementOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus())) == 0) {
  123 + throw exception(MOVEMENT_ORDER_STATUS_NOT_PREPARE);
  124 + }
121 } 125 }
122 126
123 @Override 127 @Override
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderServiceImpl.java
@@ -105,8 +105,10 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService { @@ -105,8 +105,10 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService {
105 List<WmsReceiptOrderDetailDO> details = receiptOrderDetailService.validateReceiptOrderDetailListExists(id); 105 List<WmsReceiptOrderDetailDO> details = receiptOrderDetailService.validateReceiptOrderDetailListExists(id);
106 106
107 // 2. 完成入库单 107 // 2. 完成入库单
108 - receiptOrderMapper.updateById(new WmsReceiptOrderDO().setId(id)  
109 - .setStatus(WmsOrderStatusEnum.FINISHED.getStatus())); 108 + if (receiptOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  109 + new WmsReceiptOrderDO().setStatus(WmsOrderStatusEnum.FINISHED.getStatus())) == 0) {
  110 + throw exception(RECEIPT_ORDER_STATUS_NOT_PREPARE);
  111 + }
110 112
111 // 3. 写入库存 113 // 3. 写入库存
112 createInventory(order, details); 114 createInventory(order, details);
@@ -119,8 +121,10 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService { @@ -119,8 +121,10 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService {
119 validateReceiptOrderPrepare(id); 121 validateReceiptOrderPrepare(id);
120 122
121 // 2. 作废入库单 123 // 2. 作废入库单
122 - receiptOrderMapper.updateById(new WmsReceiptOrderDO().setId(id)  
123 - .setStatus(WmsOrderStatusEnum.CANCELED.getStatus())); 124 + if (receiptOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  125 + new WmsReceiptOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus())) == 0) {
  126 + throw exception(RECEIPT_ORDER_STATUS_NOT_PREPARE);
  127 + }
124 } 128 }
125 129
126 @Override 130 @Override
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderServiceImpl.java
@@ -105,8 +105,10 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService { @@ -105,8 +105,10 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService {
105 List<WmsShipmentOrderDetailDO> details = shipmentOrderDetailService.validateShipmentOrderDetailListExists(id); 105 List<WmsShipmentOrderDetailDO> details = shipmentOrderDetailService.validateShipmentOrderDetailListExists(id);
106 106
107 // 2. 完成出库单 107 // 2. 完成出库单
108 - shipmentOrderMapper.updateById(new WmsShipmentOrderDO().setId(id)  
109 - .setStatus(WmsOrderStatusEnum.FINISHED.getStatus())); 108 + if (shipmentOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  109 + new WmsShipmentOrderDO().setStatus(WmsOrderStatusEnum.FINISHED.getStatus())) == 0) {
  110 + throw exception(SHIPMENT_ORDER_STATUS_NOT_PREPARE);
  111 + }
110 112
111 // 3. 扣减库存 113 // 3. 扣减库存
112 changeInventory(order, details); 114 changeInventory(order, details);
@@ -119,8 +121,10 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService { @@ -119,8 +121,10 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService {
119 validateShipmentOrderPrepare(id); 121 validateShipmentOrderPrepare(id);
120 122
121 // 2. 作废出库单 123 // 2. 作废出库单
122 - shipmentOrderMapper.updateById(new WmsShipmentOrderDO().setId(id)  
123 - .setStatus(WmsOrderStatusEnum.CANCELED.getStatus())); 124 + if (shipmentOrderMapper.updateByIdAndStatus(id, WmsOrderStatusEnum.PREPARE.getStatus(),
  125 + new WmsShipmentOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus())) == 0) {
  126 + throw exception(SHIPMENT_ORDER_STATUS_NOT_PREPARE);
  127 + }
124 } 128 }
125 129
126 @Override 130 @Override
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryServiceImplTest.java
@@ -320,6 +320,30 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -320,6 +320,30 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
320 } 320 }
321 321
322 @Test 322 @Test
  323 + public void testGetInventoryPage_onlyPositiveQuantity() {
  324 + // mock 数据
  325 + WmsItemDO item = createItem("ITEM-001", "红富士苹果");
  326 + WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
  327 + inventoryMapper.insert(createInventory(sku.getId(), 100L, "0.00"));
  328 + inventoryMapper.insert(createInventory(sku.getId(), 200L, "0.01"));
  329 + inventoryMapper.insert(createInventory(sku.getId(), 300L, "1.00"));
  330 + // 准备参数
  331 + WmsInventoryPageReqVO reqVO = new WmsInventoryPageReqVO();
  332 + reqVO.setType(WmsInventoryPageReqVO.TYPE_WAREHOUSE);
  333 + reqVO.setOnlyPositiveQuantity(true);
  334 +
  335 + // 调用
  336 + PageResult<WmsInventoryDO> pageResult = inventoryService.getInventoryPage(reqVO);
  337 + // 断言
  338 + assertEquals(2, pageResult.getTotal());
  339 + assertEquals(2, pageResult.getList().size());
  340 + assertEquals(200L, pageResult.getList().get(0).getWarehouseId());
  341 + assertEquals(0, new BigDecimal("0.01").compareTo(pageResult.getList().get(0).getQuantity()));
  342 + assertEquals(300L, pageResult.getList().get(1).getWarehouseId());
  343 + assertEquals(0, new BigDecimal("1.00").compareTo(pageResult.getList().get(1).getQuantity()));
  344 + }
  345 +
  346 + @Test
323 public void testGetInventoryPage_sku() { 347 public void testGetInventoryPage_sku() {
324 // mock 数据 348 // mock 数据
325 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 349 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImplTest.java
@@ -27,6 +27,7 @@ import java.util.List; @@ -27,6 +27,7 @@ import java.util.List;
27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
28 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_DETAIL_REQUIRED; 28 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_DETAIL_REQUIRED;
29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_DELETABLE; 29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_DELETABLE;
  30 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_PREPARE;
30 import static org.junit.jupiter.api.Assertions.assertEquals; 31 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertNotNull; 32 import static org.junit.jupiter.api.Assertions.assertNotNull;
32 import static org.junit.jupiter.api.Assertions.assertNull; 33 import static org.junit.jupiter.api.Assertions.assertNull;
@@ -162,6 +163,23 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { @@ -162,6 +163,23 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest {
162 } 163 }
163 164
164 @Test 165 @Test
  166 + public void testCompleteCheckOrder_duplicateComplete() {
  167 + // mock 数据
  168 + WmsCheckOrderDO order = createCheckOrder(100L);
  169 + checkOrderMapper.insert(order);
  170 + checkOrderDetailMapper.insert(createCheckOrderDetail(order.getId(), 200L, 100L,
  171 + "10.00", "7.00"));
  172 +
  173 + // 调用
  174 + checkOrderService.completeCheckOrder(order.getId());
  175 +
  176 + // 调用,并断言:二次完成不能再次写库存
  177 + assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()),
  178 + CHECK_ORDER_STATUS_NOT_PREPARE);
  179 + verify(inventoryService).changeInventory(any());
  180 + }
  181 +
  182 + @Test
165 public void testCancelCheckOrder_success() { 183 public void testCancelCheckOrder_success() {
166 // mock 数据 184 // mock 数据
167 WmsCheckOrderDO order = createCheckOrder(100L); 185 WmsCheckOrderDO order = createCheckOrder(100L);
@@ -178,6 +196,23 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest { @@ -178,6 +196,23 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest {
178 } 196 }
179 197
180 @Test 198 @Test
  199 + public void testUpdateByIdAndStatus_statusNotMatch() {
  200 + // mock 数据
  201 + WmsCheckOrderDO order = createCheckOrder(100L);
  202 + checkOrderMapper.insert(order);
  203 +
  204 + // 调用
  205 + int updateCount = checkOrderMapper.updateByIdAndStatus(order.getId(),
  206 + WmsOrderStatusEnum.FINISHED.getStatus(),
  207 + new WmsCheckOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus()));
  208 +
  209 + // 断言
  210 + assertEquals(0, updateCount);
  211 + assertEquals(WmsOrderStatusEnum.PREPARE.getStatus(),
  212 + checkOrderMapper.selectById(order.getId()).getStatus());
  213 + }
  214 +
  215 + @Test
181 public void testDeleteCheckOrder_canceled() { 216 public void testDeleteCheckOrder_canceled() {
182 // mock 数据 217 // mock 数据
183 WmsCheckOrderDO order = createCheckOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus()); 218 WmsCheckOrderDO order = createCheckOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderServiceImplTest.java
@@ -26,6 +26,7 @@ import java.util.Arrays; @@ -26,6 +26,7 @@ import java.util.Arrays;
26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
27 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_DETAIL_REQUIRED; 27 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_DETAIL_REQUIRED;
28 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_STATUS_NOT_DELETABLE; 28 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_STATUS_NOT_DELETABLE;
  29 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_STATUS_NOT_PREPARE;
29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_WAREHOUSE_SAME; 30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_WAREHOUSE_SAME;
30 import static org.junit.jupiter.api.Assertions.assertEquals; 31 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertNotNull; 32 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -136,6 +137,22 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest { @@ -136,6 +137,22 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
136 } 137 }
137 138
138 @Test 139 @Test
  140 + public void testCompleteMovementOrder_duplicateComplete() {
  141 + // mock 数据
  142 + WmsMovementOrderDO order = createMovementOrder(100L, 200L);
  143 + movementOrderMapper.insert(order);
  144 + movementOrderDetailMapper.insert(createMovementOrderDetail(order.getId(), 300L, 100L, 200L));
  145 +
  146 + // 调用
  147 + movementOrderService.completeMovementOrder(order.getId());
  148 +
  149 + // 调用,并断言:二次完成不能再次写库存
  150 + assertServiceException(() -> movementOrderService.completeMovementOrder(order.getId()),
  151 + MOVEMENT_ORDER_STATUS_NOT_PREPARE);
  152 + verify(inventoryService).changeInventory(any());
  153 + }
  154 +
  155 + @Test
139 public void testCreateMovementOrder_sameWarehouse() { 156 public void testCreateMovementOrder_sameWarehouse() {
140 // 准备参数 157 // 准备参数
141 WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(100L, 100L); 158 WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(100L, 100L);
@@ -162,6 +179,23 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest { @@ -162,6 +179,23 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
162 } 179 }
163 180
164 @Test 181 @Test
  182 + public void testUpdateByIdAndStatus_statusNotMatch() {
  183 + // mock 数据
  184 + WmsMovementOrderDO order = createMovementOrder(100L, 200L);
  185 + movementOrderMapper.insert(order);
  186 +
  187 + // 调用
  188 + int updateCount = movementOrderMapper.updateByIdAndStatus(order.getId(),
  189 + WmsOrderStatusEnum.FINISHED.getStatus(),
  190 + new WmsMovementOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus()));
  191 +
  192 + // 断言
  193 + assertEquals(0, updateCount);
  194 + assertEquals(WmsOrderStatusEnum.PREPARE.getStatus(),
  195 + movementOrderMapper.selectById(order.getId()).getStatus());
  196 + }
  197 +
  198 + @Test
165 public void testDeleteMovementOrder_canceled() { 199 public void testDeleteMovementOrder_canceled() {
166 // mock 数据 200 // mock 数据
167 WmsMovementOrderDO order = createMovementOrder(100L, 200L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus()); 201 WmsMovementOrderDO order = createMovementOrder(100L, 200L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderServiceImplTest.java
@@ -27,6 +27,7 @@ import java.util.Arrays; @@ -27,6 +27,7 @@ import java.util.Arrays;
27 27
28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_DETAIL_REQUIRED; 29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_DETAIL_REQUIRED;
  30 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_STATUS_NOT_PREPARE;
30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_STATUS_NOT_DELETABLE; 31 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_STATUS_NOT_DELETABLE;
31 import static org.junit.jupiter.api.Assertions.assertEquals; 32 import static org.junit.jupiter.api.Assertions.assertEquals;
32 import static org.junit.jupiter.api.Assertions.assertNotNull; 33 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -134,6 +135,22 @@ public class WmsReceiptOrderServiceImplTest extends BaseDbUnitTest { @@ -134,6 +135,22 @@ public class WmsReceiptOrderServiceImplTest extends BaseDbUnitTest {
134 } 135 }
135 136
136 @Test 137 @Test
  138 + public void testCompleteReceiptOrder_duplicateComplete() {
  139 + // mock 数据
  140 + WmsReceiptOrderDO order = createReceiptOrder(100L);
  141 + receiptOrderMapper.insert(order);
  142 + receiptOrderDetailMapper.insert(createReceiptOrderDetail(order.getId(), 200L, 100L));
  143 +
  144 + // 调用
  145 + receiptOrderService.completeReceiptOrder(order.getId());
  146 +
  147 + // 调用,并断言:二次完成不能再次写库存
  148 + assertServiceException(() -> receiptOrderService.completeReceiptOrder(order.getId()),
  149 + RECEIPT_ORDER_STATUS_NOT_PREPARE);
  150 + verify(inventoryService).changeInventory(any());
  151 + }
  152 +
  153 + @Test
137 public void testCancelReceiptOrder_success() { 154 public void testCancelReceiptOrder_success() {
138 // mock 数据 155 // mock 数据
139 WmsReceiptOrderDO order = createReceiptOrder(100L); 156 WmsReceiptOrderDO order = createReceiptOrder(100L);
@@ -150,6 +167,23 @@ public class WmsReceiptOrderServiceImplTest extends BaseDbUnitTest { @@ -150,6 +167,23 @@ public class WmsReceiptOrderServiceImplTest extends BaseDbUnitTest {
150 } 167 }
151 168
152 @Test 169 @Test
  170 + public void testUpdateByIdAndStatus_statusNotMatch() {
  171 + // mock 数据
  172 + WmsReceiptOrderDO order = createReceiptOrder(100L);
  173 + receiptOrderMapper.insert(order);
  174 +
  175 + // 调用
  176 + int updateCount = receiptOrderMapper.updateByIdAndStatus(order.getId(),
  177 + WmsOrderStatusEnum.FINISHED.getStatus(),
  178 + new WmsReceiptOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus()));
  179 +
  180 + // 断言
  181 + assertEquals(0, updateCount);
  182 + assertEquals(WmsOrderStatusEnum.PREPARE.getStatus(),
  183 + receiptOrderMapper.selectById(order.getId()).getStatus());
  184 + }
  185 +
  186 + @Test
153 public void testDeleteReceiptOrder_canceled() { 187 public void testDeleteReceiptOrder_canceled() {
154 // mock 数据 188 // mock 数据
155 WmsReceiptOrderDO order = createReceiptOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus()); 189 WmsReceiptOrderDO order = createReceiptOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderServiceImplTest.java
@@ -28,6 +28,7 @@ import java.util.Arrays; @@ -28,6 +28,7 @@ import java.util.Arrays;
28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_DETAIL_REQUIRED; 29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_DETAIL_REQUIRED;
30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_STATUS_NOT_DELETABLE; 30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_STATUS_NOT_DELETABLE;
  31 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_STATUS_NOT_PREPARE;
31 import static org.junit.jupiter.api.Assertions.assertEquals; 32 import static org.junit.jupiter.api.Assertions.assertEquals;
32 import static org.junit.jupiter.api.Assertions.assertNotNull; 33 import static org.junit.jupiter.api.Assertions.assertNotNull;
33 import static org.junit.jupiter.api.Assertions.assertNull; 34 import static org.junit.jupiter.api.Assertions.assertNull;
@@ -134,6 +135,22 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { @@ -134,6 +135,22 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
134 } 135 }
135 136
136 @Test 137 @Test
  138 + public void testCompleteShipmentOrder_duplicateComplete() {
  139 + // mock 数据
  140 + WmsShipmentOrderDO order = createShipmentOrder(100L);
  141 + shipmentOrderMapper.insert(order);
  142 + shipmentOrderDetailMapper.insert(createShipmentOrderDetail(order.getId(), 200L, 100L));
  143 +
  144 + // 调用
  145 + shipmentOrderService.completeShipmentOrder(order.getId());
  146 +
  147 + // 调用,并断言:二次完成不能再次写库存
  148 + assertServiceException(() -> shipmentOrderService.completeShipmentOrder(order.getId()),
  149 + SHIPMENT_ORDER_STATUS_NOT_PREPARE);
  150 + verify(inventoryService).changeInventory(any());
  151 + }
  152 +
  153 + @Test
137 public void testCancelShipmentOrder_success() { 154 public void testCancelShipmentOrder_success() {
138 // mock 数据 155 // mock 数据
139 WmsShipmentOrderDO order = createShipmentOrder(100L); 156 WmsShipmentOrderDO order = createShipmentOrder(100L);
@@ -150,6 +167,23 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { @@ -150,6 +167,23 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
150 } 167 }
151 168
152 @Test 169 @Test
  170 + public void testUpdateByIdAndStatus_statusNotMatch() {
  171 + // mock 数据
  172 + WmsShipmentOrderDO order = createShipmentOrder(100L);
  173 + shipmentOrderMapper.insert(order);
  174 +
  175 + // 调用
  176 + int updateCount = shipmentOrderMapper.updateByIdAndStatus(order.getId(),
  177 + WmsOrderStatusEnum.FINISHED.getStatus(),
  178 + new WmsShipmentOrderDO().setStatus(WmsOrderStatusEnum.CANCELED.getStatus()));
  179 +
  180 + // 断言
  181 + assertEquals(0, updateCount);
  182 + assertEquals(WmsOrderStatusEnum.PREPARE.getStatus(),
  183 + shipmentOrderMapper.selectById(order.getId()).getStatus());
  184 + }
  185 +
  186 + @Test
153 public void testDeleteShipmentOrder_canceled() { 187 public void testDeleteShipmentOrder_canceled() {
154 // mock 数据 188 // mock 数据
155 WmsShipmentOrderDO order = createShipmentOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus()); 189 WmsShipmentOrderDO order = createShipmentOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());