Commit 65a1337dbd1b74ca5f1317ae708b007e82dbebbc

Authored by YunaiV
1 parent 273d911e

feat(wms):移库管理,调整合计金额、数量的字段与交互。(前端负责展示,后端负责计算)

yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/detail/WmsMovementOrderDetailRespVO.java
... ... @@ -52,8 +52,8 @@ public class WmsMovementOrderDetailRespVO {
52 52 @Schema(description = "移库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
53 53 private BigDecimal quantity;
54 54  
55   - @Schema(description = "金额", example = "1000.00")
56   - private BigDecimal amount;
  55 + @Schema(description = "单价", example = "100.00")
  56 + private BigDecimal price;
57 57  
58 58 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
59 59 private LocalDateTime createTime;
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/detail/WmsMovementOrderDetailSaveReqVO.java
... ... @@ -23,8 +23,8 @@ public class WmsMovementOrderDetailSaveReqVO {
23 23 @DecimalMin(value = "0", inclusive = false, message = "移库数量必须大于 0")
24 24 private BigDecimal quantity;
25 25  
26   - @Schema(description = "金额", example = "1000.00")
27   - @DecimalMin(value = "0", message = "金额不能小于 0")
28   - private BigDecimal amount;
  26 + @Schema(description = "单价", example = "100.00")
  27 + @DecimalMin(value = "0", message = "单价不能小于 0")
  28 + private BigDecimal price;
29 29  
30 30 }
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/order/WmsMovementOrderPageReqVO.java
... ... @@ -44,10 +44,10 @@ public class WmsMovementOrderPageReqVO extends PageParam {
44 44 private BigDecimal totalQuantityMax;
45 45  
46 46 @Schema(description = "最小总金额", example = "1.00")
47   - private BigDecimal totalAmountMin;
  47 + private BigDecimal totalPriceMin;
48 48  
49 49 @Schema(description = "最大总金额", example = "1000.00")
50   - private BigDecimal totalAmountMax;
  50 + private BigDecimal totalPriceMax;
51 51  
52 52 @Schema(description = "创建用户", example = "1")
53 53 private String creator;
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/order/WmsMovementOrderRespVO.java
... ... @@ -57,7 +57,7 @@ public class WmsMovementOrderRespVO {
57 57  
58 58 @Schema(description = "总金额", example = "1000.00")
59 59 @ExcelProperty("总金额")
60   - private BigDecimal totalAmount;
  60 + private BigDecimal totalPrice;
61 61  
62 62 @Schema(description = "移库明细")
63 63 private List<WmsMovementOrderDetailRespVO> details;
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/order/WmsMovementOrderSaveReqVO.java
... ... @@ -8,7 +8,6 @@ import jakarta.validation.constraints.NotNull;
8 8 import jakarta.validation.constraints.Size;
9 9 import lombok.Data;
10 10  
11   -import java.math.BigDecimal;
12 11 import java.time.LocalDateTime;
13 12 import java.util.List;
14 13  
... ... @@ -40,14 +39,6 @@ public class WmsMovementOrderSaveReqVO {
40 39 @NotNull(message = "目标仓库不能为空")
41 40 private Long targetWarehouseId;
42 41  
43   - @Schema(description = "移库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
44   - @NotNull(message = "移库数量不能为空")
45   - private BigDecimal totalQuantity;
46   -
47   - @Schema(description = "总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00")
48   - @NotNull(message = "总金额不能为空")
49   - private BigDecimal totalAmount;
50   -
51 42 @Schema(description = "移库明细")
52 43 @Valid
53 44 private List<WmsMovementOrderDetailSaveReqVO> details;
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/movement/WmsMovementOrderDO.java
... ... @@ -77,6 +77,6 @@ public class WmsMovementOrderDO extends BaseDO {
77 77 /**
78 78 * 总金额
79 79 */
80   - private BigDecimal totalAmount;
  80 + private BigDecimal totalPrice;
81 81  
82 82 }
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/movement/WmsMovementOrderDetailDO.java
... ... @@ -70,8 +70,8 @@ public class WmsMovementOrderDetailDO extends BaseDO {
70 70 */
71 71 private BigDecimal quantity;
72 72 /**
73   - * 金额(小计、非单价)
  73 + * 单价
74 74 */
75   - private BigDecimal amount;
  75 + private BigDecimal price;
76 76  
77 77 }
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/movement/WmsMovementOrderMapper.java
... ... @@ -24,8 +24,8 @@ public interface WmsMovementOrderMapper extends BaseMapperX&lt;WmsMovementOrderDO&gt;
24 24 .betweenIfPresent(WmsMovementOrderDO::getOrderTime, reqVO.getOrderTime())
25 25 .geIfPresent(WmsMovementOrderDO::getTotalQuantity, reqVO.getTotalQuantityMin())
26 26 .leIfPresent(WmsMovementOrderDO::getTotalQuantity, reqVO.getTotalQuantityMax())
27   - .geIfPresent(WmsMovementOrderDO::getTotalAmount, reqVO.getTotalAmountMin())
28   - .leIfPresent(WmsMovementOrderDO::getTotalAmount, reqVO.getTotalAmountMax())
  27 + .geIfPresent(WmsMovementOrderDO::getTotalPrice, reqVO.getTotalPriceMin())
  28 + .leIfPresent(WmsMovementOrderDO::getTotalPrice, reqVO.getTotalPriceMax())
29 29 .eqIfPresent(WmsMovementOrderDO::getCreator, reqVO.getCreator())
30 30 .eqIfPresent(WmsMovementOrderDO::getUpdater, reqVO.getUpdater())
31 31 .betweenIfPresent(WmsMovementOrderDO::getCreateTime, reqVO.getCreateTime())
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderServiceImpl.java
1 1 package cn.iocoder.yudao.module.wms.service.order.movement;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 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;
  7 +import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.detail.WmsMovementOrderDetailSaveReqVO;
6 8 import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderPageReqVO;
7 9 import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderSaveReqVO;
8 10 import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDO;
... ... @@ -18,6 +20,7 @@ import org.springframework.stereotype.Service;
18 20 import org.springframework.transaction.annotation.Transactional;
19 21 import org.springframework.validation.annotation.Validated;
20 22  
  23 +import java.math.BigDecimal;
21 24 import java.util.ArrayList;
22 25 import java.util.List;
23 26  
... ... @@ -51,6 +54,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
51 54 // 2.1 插入移库单
52 55 WmsMovementOrderDO order = BeanUtils.toBean(createReqVO, WmsMovementOrderDO.class);
53 56 order.setStatus(WmsOrderStatusEnum.PREPARE.getStatus());
  57 + fillMovementOrderTotal(order, createReqVO);
54 58 movementOrderMapper.insert(order);
55 59 // 2.2 插入移库单明细
56 60 movementOrderDetailService.createMovementOrderDetailList(order.getId(), createReqVO);
... ... @@ -67,6 +71,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
67 71 // 2.1 更新移库单
68 72 WmsMovementOrderDO updateObj = BeanUtils.toBean(updateReqVO, WmsMovementOrderDO.class)
69 73 .setStatus(WmsOrderStatusEnum.PREPARE.getStatus());
  74 + fillMovementOrderTotal(updateObj, updateReqVO);
70 75 movementOrderMapper.updateById(updateObj);
71 76 // 2.2 更新移库单明细
72 77 movementOrderDetailService.updateMovementOrderDetailList(updateReqVO.getId(), updateReqVO);
... ... @@ -152,6 +157,22 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
152 157 }
153 158 }
154 159  
  160 + private void fillMovementOrderTotal(WmsMovementOrderDO order, WmsMovementOrderSaveReqVO reqVO) {
  161 + BigDecimal totalQuantity = BigDecimal.ZERO;
  162 + BigDecimal totalPrice = BigDecimal.ZERO;
  163 + if (CollUtil.isNotEmpty(reqVO.getDetails())) {
  164 + for (WmsMovementOrderDetailSaveReqVO detail : reqVO.getDetails()) {
  165 + if (detail.getQuantity() != null) {
  166 + totalQuantity = totalQuantity.add(detail.getQuantity());
  167 + }
  168 + if (detail.getQuantity() != null && detail.getPrice() != null) {
  169 + totalPrice = totalPrice.add(detail.getQuantity().multiply(detail.getPrice()));
  170 + }
  171 + }
  172 + }
  173 + order.setTotalQuantity(totalQuantity).setTotalPrice(totalPrice);
  174 + }
  175 +
155 176 private WmsMovementOrderDO validateMovementOrderExists(Long id) {
156 177 WmsMovementOrderDO order = id == null ? null : movementOrderMapper.selectById(id);
157 178 if (order == null) {
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderDetailServiceImplTest.java
... ... @@ -131,7 +131,7 @@ public class WmsMovementOrderDetailServiceImplTest extends BaseDbUnitTest {
131 131 reqVO.setId(id);
132 132 reqVO.setSkuId(skuId);
133 133 reqVO.setQuantity(new BigDecimal(quantity));
134   - reqVO.setAmount(new BigDecimal("100.00"));
  134 + reqVO.setPrice(new BigDecimal("100.00"));
135 135 return reqVO;
136 136 }
137 137  
... ... @@ -142,7 +142,7 @@ public class WmsMovementOrderDetailServiceImplTest extends BaseDbUnitTest {
142 142 .sourceWarehouseId(100L)
143 143 .targetWarehouseId(200L)
144 144 .quantity(new BigDecimal(quantity))
145   - .amount(new BigDecimal("100.00"))
  145 + .price(new BigDecimal("100.00"))
146 146 .build();
147 147 }
148 148  
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderServiceImplTest.java
1 1 package cn.iocoder.yudao.module.wms.service.order.movement;
2 2  
3 3 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.detail.WmsMovementOrderDetailSaveReqVO;
4 5 import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderSaveReqVO;
5 6 import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDO;
6 7 import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDetailDO;
... ... @@ -20,6 +21,7 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean;
20 21  
21 22 import java.math.BigDecimal;
22 23 import java.time.LocalDateTime;
  24 +import java.util.Arrays;
23 25  
24 26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
25 27 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_DETAIL_REQUIRED;
... ... @@ -51,6 +53,43 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
51 53 private WmsInventoryService inventoryService;
52 54  
53 55 @Test
  56 + public void testCreateMovementOrder_calculateTotal() {
  57 + // mock 数据
  58 + WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(null, 100L, 200L,
  59 + createMovementOrderDetailReqVO(null, 3001L, "1.50", "10.00"),
  60 + createMovementOrderDetailReqVO(null, 3002L, "2.50", "20.00"));
  61 +
  62 + // 调用
  63 + Long orderId = movementOrderService.createMovementOrder(reqVO);
  64 +
  65 + // 断言
  66 + WmsMovementOrderDO dbOrder = movementOrderMapper.selectById(orderId);
  67 + assertNotNull(dbOrder);
  68 + assertEquals(0, new BigDecimal("4.00").compareTo(dbOrder.getTotalQuantity()));
  69 + assertEquals(0, new BigDecimal("65.00").compareTo(dbOrder.getTotalPrice()));
  70 + assertEquals(2, movementOrderDetailMapper.selectListByOrderId(orderId).size());
  71 + }
  72 +
  73 + @Test
  74 + public void testUpdateMovementOrder_calculateTotal() {
  75 + // mock 数据
  76 + WmsMovementOrderDO order = createMovementOrder(100L, 200L);
  77 + movementOrderMapper.insert(order);
  78 + WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(order.getId(), 100L, 200L,
  79 + createMovementOrderDetailReqVO(null, 3001L, "3.00", "30.00"));
  80 +
  81 + // 调用
  82 + movementOrderService.updateMovementOrder(reqVO);
  83 +
  84 + // 断言
  85 + WmsMovementOrderDO dbOrder = movementOrderMapper.selectById(order.getId());
  86 + assertNotNull(dbOrder);
  87 + assertEquals(0, new BigDecimal("3.00").compareTo(dbOrder.getTotalQuantity()));
  88 + assertEquals(0, new BigDecimal("90.00").compareTo(dbOrder.getTotalPrice()));
  89 + assertEquals(1, movementOrderDetailMapper.selectListByOrderId(order.getId()).size());
  90 + }
  91 +
  92 + @Test
54 93 public void testCompleteMovementOrder_success() {
55 94 // mock 数据
56 95 Long sourceWarehouseId = 100L;
... ... @@ -156,7 +195,7 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
156 195 .setSourceWarehouseId(sourceWarehouseId)
157 196 .setTargetWarehouseId(targetWarehouseId)
158 197 .setTotalQuantity(new BigDecimal("2.00"))
159   - .setTotalAmount(new BigDecimal("20.00"));
  198 + .setTotalPrice(new BigDecimal("20.00"));
160 199 }
161 200  
162 201 private static WmsMovementOrderDetailDO createMovementOrderDetail(Long orderId, Long skuId,
... ... @@ -167,18 +206,34 @@ public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
167 206 .sourceWarehouseId(sourceWarehouseId)
168 207 .targetWarehouseId(targetWarehouseId)
169 208 .quantity(new BigDecimal("2.00"))
170   - .amount(new BigDecimal("20.00"))
  209 + .price(new BigDecimal("20.00"))
171 210 .build();
172 211 }
173 212  
174 213 private static WmsMovementOrderSaveReqVO createMovementOrderReqVO(Long sourceWarehouseId, Long targetWarehouseId) {
  214 + return createMovementOrderReqVO(null, sourceWarehouseId, targetWarehouseId);
  215 + }
  216 +
  217 + private static WmsMovementOrderSaveReqVO createMovementOrderReqVO(Long id, Long sourceWarehouseId,
  218 + Long targetWarehouseId,
  219 + WmsMovementOrderDetailSaveReqVO... details) {
175 220 WmsMovementOrderSaveReqVO reqVO = new WmsMovementOrderSaveReqVO();
  221 + reqVO.setId(id);
176 222 reqVO.setNo("YK202605120001");
177 223 reqVO.setOrderTime(LocalDateTime.of(2026, 5, 12, 0, 0));
178 224 reqVO.setSourceWarehouseId(sourceWarehouseId);
179 225 reqVO.setTargetWarehouseId(targetWarehouseId);
180   - reqVO.setTotalQuantity(new BigDecimal("2.00"));
181   - reqVO.setTotalAmount(new BigDecimal("20.00"));
  226 + reqVO.setDetails(Arrays.asList(details));
  227 + return reqVO;
  228 + }
  229 +
  230 + private static WmsMovementOrderDetailSaveReqVO createMovementOrderDetailReqVO(Long id, Long skuId,
  231 + String quantity, String price) {
  232 + WmsMovementOrderDetailSaveReqVO reqVO = new WmsMovementOrderDetailSaveReqVO();
  233 + reqVO.setId(id);
  234 + reqVO.setSkuId(skuId);
  235 + reqVO.setQuantity(new BigDecimal(quantity));
  236 + reqVO.setPrice(new BigDecimal(price));
182 237 return reqVO;
183 238 }
184 239  
... ...
yudao-module-wms/src/test/resources/sql/create_tables.sql
... ... @@ -157,7 +157,7 @@ CREATE TABLE IF NOT EXISTS &quot;wms_movement_order&quot; (
157 157 "source_warehouse_id" bigint NOT NULL,
158 158 "target_warehouse_id" bigint NOT NULL,
159 159 "total_quantity" decimal(20, 2) NOT NULL DEFAULT '0',
160   - "total_amount" decimal(10, 2) DEFAULT NULL,
  160 + "total_price" decimal(10, 2) DEFAULT NULL,
161 161 "creator" varchar(64) DEFAULT '',
162 162 "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
163 163 "updater" varchar(64) DEFAULT '',
... ... @@ -174,7 +174,7 @@ CREATE TABLE IF NOT EXISTS &quot;wms_movement_order_detail&quot; (
174 174 "source_warehouse_id" bigint NOT NULL,
175 175 "target_warehouse_id" bigint NOT NULL,
176 176 "quantity" decimal(20, 2) NOT NULL DEFAULT '0',
177   - "amount" decimal(10, 2) DEFAULT NULL,
  177 + "price" decimal(10, 2) DEFAULT NULL,
178 178 "creator" varchar(64) DEFAULT '',
179 179 "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
180 180 "updater" varchar(64) DEFAULT '',
... ...