Commit 32813c08739b86d51c6ee8437caf0d74f8140f4e
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<WmsMovementOrderDO> |
| 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<WmsReceiptOrderDO> { |
| 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<WmsShipmentOrderDO> |
| 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()); | ... | ... |