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 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.wms.controller.admin.order.check.vo.order.WmsCheckOrderPageReqVO;
7 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.check.WmsCheckOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 9 import org.apache.ibatis.annotations.Mapper;
9 10  
10 11 /**
... ... @@ -42,4 +43,10 @@ public interface WmsCheckOrderMapper extends BaseMapperX<WmsCheckOrderDO> {
42 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 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderPageReqVO;
7 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 9 import org.apache.ibatis.annotations.Mapper;
9 10  
10 11 /**
... ... @@ -43,4 +44,10 @@ public interface WmsMovementOrderMapper extends BaseMapperX&lt;WmsMovementOrderDO&gt;
43 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 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderPageReqVO;
7 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 9 import org.apache.ibatis.annotations.Mapper;
9 10  
10 11 /**
... ... @@ -47,4 +48,10 @@ public interface WmsReceiptOrderMapper extends BaseMapperX&lt;WmsReceiptOrderDO&gt; {
47 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 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.order.WmsShipmentOrderPageReqVO;
7 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment.WmsShipmentOrderDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 9 import org.apache.ibatis.annotations.Mapper;
9 10  
10 11 /**
... ... @@ -47,4 +48,10 @@ public interface WmsShipmentOrderMapper extends BaseMapperX&lt;WmsShipmentOrderDO&gt;
47 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 102 List<WmsCheckOrderDetailDO> details = checkOrderDetailService.validateCheckOrderDetailListExists(id);
103 103  
104 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 110 // 3. 盘点库存
109 111 changeInventory(order, details);
... ... @@ -116,8 +118,10 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
116 118 validateCheckOrderPrepare(id);
117 119  
118 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 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 102 List<WmsMovementOrderDetailDO> details = movementOrderDetailService.validateMovementOrderDetailListExists(id);
103 103  
104 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 110 // 3. 移动库存
109 111 changeInventory(order, details);
... ... @@ -116,8 +118,10 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
116 118 validateMovementOrderPrepare(id);
117 119  
118 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 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 105 List<WmsReceiptOrderDetailDO> details = receiptOrderDetailService.validateReceiptOrderDetailListExists(id);
106 106  
107 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 113 // 3. 写入库存
112 114 createInventory(order, details);
... ... @@ -119,8 +121,10 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService {
119 121 validateReceiptOrderPrepare(id);
120 122  
121 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 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 105 List<WmsShipmentOrderDetailDO> details = shipmentOrderDetailService.validateShipmentOrderDetailListExists(id);
106 106  
107 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 113 // 3. 扣减库存
112 114 changeInventory(order, details);
... ... @@ -119,8 +121,10 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService {
119 121 validateShipmentOrderPrepare(id);
120 122  
121 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 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 320 }
321 321  
322 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 347 public void testGetInventoryPage_sku() {
324 348 // mock 数据
325 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 27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
28 28 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_DETAIL_REQUIRED;
29 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 31 import static org.junit.jupiter.api.Assertions.assertEquals;
31 32 import static org.junit.jupiter.api.Assertions.assertNotNull;
32 33 import static org.junit.jupiter.api.Assertions.assertNull;
... ... @@ -162,6 +163,23 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest {
162 163 }
163 164  
164 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 183 public void testCancelCheckOrder_success() {
166 184 // mock 数据
167 185 WmsCheckOrderDO order = createCheckOrder(100L);
... ... @@ -178,6 +196,23 @@ public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest {
178 196 }
179 197  
180 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 216 public void testDeleteCheckOrder_canceled() {
182 217 // mock 数据
183 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 26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
27 27 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_DETAIL_REQUIRED;
28 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 30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_WAREHOUSE_SAME;
30 31 import static org.junit.jupiter.api.Assertions.assertEquals;
31 32 import static org.junit.jupiter.api.Assertions.assertNotNull;
... ... @@ -136,6 +137,22 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
136 137 }
137 138  
138 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 156 public void testCreateMovementOrder_sameWarehouse() {
140 157 // 准备参数
141 158 WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(100L, 100L);
... ... @@ -162,6 +179,23 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
162 179 }
163 180  
164 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 199 public void testDeleteMovementOrder_canceled() {
166 200 // mock 数据
167 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 27  
28 28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
29 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 31 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_STATUS_NOT_DELETABLE;
31 32 import static org.junit.jupiter.api.Assertions.assertEquals;
32 33 import static org.junit.jupiter.api.Assertions.assertNotNull;
... ... @@ -134,6 +135,22 @@ public class WmsReceiptOrderServiceImplTest extends BaseDbUnitTest {
134 135 }
135 136  
136 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 154 public void testCancelReceiptOrder_success() {
138 155 // mock 数据
139 156 WmsReceiptOrderDO order = createReceiptOrder(100L);
... ... @@ -150,6 +167,23 @@ public class WmsReceiptOrderServiceImplTest extends BaseDbUnitTest {
150 167 }
151 168  
152 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 187 public void testDeleteReceiptOrder_canceled() {
154 188 // mock 数据
155 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 28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
29 29 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_DETAIL_REQUIRED;
30 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 32 import static org.junit.jupiter.api.Assertions.assertEquals;
32 33 import static org.junit.jupiter.api.Assertions.assertNotNull;
33 34 import static org.junit.jupiter.api.Assertions.assertNull;
... ... @@ -134,6 +135,22 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
134 135 }
135 136  
136 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 154 public void testCancelShipmentOrder_success() {
138 155 // mock 数据
139 156 WmsShipmentOrderDO order = createShipmentOrder(100L);
... ... @@ -150,6 +167,23 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
150 167 }
151 168  
152 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 187 public void testDeleteShipmentOrder_canceled() {
154 188 // mock 数据
155 189 WmsShipmentOrderDO order = createShipmentOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
... ...