Commit 273d911edc75b2e96362c4f27bd649117b49cfdd
1 parent
70a6316c
feat(wms):出库管理,调整合计金额、数量的字段与交互。(前端负责展示,后端负责计算)
Showing
12 changed files
with
101 additions
and
28 deletions
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/detail/WmsShipmentOrderDetailRespVO.java
| ... | ... | @@ -46,8 +46,8 @@ public class WmsShipmentOrderDetailRespVO { |
| 46 | 46 | @Schema(description = "出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| 47 | 47 | private BigDecimal quantity; |
| 48 | 48 | |
| 49 | - @Schema(description = "金额", example = "1000.00") | |
| 50 | - private BigDecimal amount; | |
| 49 | + @Schema(description = "单价", example = "100.00") | |
| 50 | + private BigDecimal price; | |
| 51 | 51 | |
| 52 | 52 | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 53 | 53 | private LocalDateTime createTime; | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/detail/WmsShipmentOrderDetailSaveReqVO.java
| ... | ... | @@ -23,8 +23,8 @@ public class WmsShipmentOrderDetailSaveReqVO { |
| 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/shipment/vo/order/WmsShipmentOrderPageReqVO.java
| ... | ... | @@ -45,10 +45,10 @@ public class WmsShipmentOrderPageReqVO extends PageParam { |
| 45 | 45 | private BigDecimal totalQuantityMax; |
| 46 | 46 | |
| 47 | 47 | @Schema(description = "最小总金额", example = "1.00") |
| 48 | - private BigDecimal totalAmountMin; | |
| 48 | + private BigDecimal totalPriceMin; | |
| 49 | 49 | |
| 50 | 50 | @Schema(description = "最大总金额", example = "1000.00") |
| 51 | - private BigDecimal totalAmountMax; | |
| 51 | + private BigDecimal totalPriceMax; | |
| 52 | 52 | |
| 53 | 53 | @Schema(description = "出库类型", example = "201") |
| 54 | 54 | @InEnum(WmsShipmentOrderTypeEnum.class) | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/order/WmsShipmentOrderRespVO.java
| ... | ... | @@ -66,7 +66,7 @@ public class WmsShipmentOrderRespVO { |
| 66 | 66 | |
| 67 | 67 | @Schema(description = "总金额", example = "1000.00") |
| 68 | 68 | @ExcelProperty("总金额") |
| 69 | - private BigDecimal totalAmount; | |
| 69 | + private BigDecimal totalPrice; | |
| 70 | 70 | |
| 71 | 71 | @Schema(description = "出库明细") |
| 72 | 72 | private List<WmsShipmentOrderDetailRespVO> details; | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/order/WmsShipmentOrderSaveReqVO.java
| ... | ... | @@ -10,7 +10,6 @@ import jakarta.validation.constraints.NotNull; |
| 10 | 10 | import jakarta.validation.constraints.Size; |
| 11 | 11 | import lombok.Data; |
| 12 | 12 | |
| 13 | -import java.math.BigDecimal; | |
| 14 | 13 | import java.time.LocalDateTime; |
| 15 | 14 | import java.util.List; |
| 16 | 15 | |
| ... | ... | @@ -50,14 +49,6 @@ public class WmsShipmentOrderSaveReqVO { |
| 50 | 49 | @NotNull(message = "仓库不能为空") |
| 51 | 50 | private Long warehouseId; |
| 52 | 51 | |
| 53 | - @Schema(description = "出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") | |
| 54 | - @NotNull(message = "出库数量不能为空") | |
| 55 | - private BigDecimal totalQuantity; | |
| 56 | - | |
| 57 | - @Schema(description = "总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00") | |
| 58 | - @NotNull(message = "总金额不能为空") | |
| 59 | - private BigDecimal totalAmount; | |
| 60 | - | |
| 61 | 52 | @Schema(description = "出库明细") |
| 62 | 53 | @Valid |
| 63 | 54 | private List<WmsShipmentOrderDetailSaveReqVO> details; | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/shipment/WmsShipmentOrderDO.java
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/shipment/WmsShipmentOrderDetailDO.java
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/shipment/WmsShipmentOrderMapper.java
| ... | ... | @@ -24,8 +24,8 @@ public interface WmsShipmentOrderMapper extends BaseMapperX<WmsShipmentOrderDO> |
| 24 | 24 | .betweenIfPresent(WmsShipmentOrderDO::getOrderTime, reqVO.getOrderTime()) |
| 25 | 25 | .geIfPresent(WmsShipmentOrderDO::getTotalQuantity, reqVO.getTotalQuantityMin()) |
| 26 | 26 | .leIfPresent(WmsShipmentOrderDO::getTotalQuantity, reqVO.getTotalQuantityMax()) |
| 27 | - .geIfPresent(WmsShipmentOrderDO::getTotalAmount, reqVO.getTotalAmountMin()) | |
| 28 | - .leIfPresent(WmsShipmentOrderDO::getTotalAmount, reqVO.getTotalAmountMax()) | |
| 27 | + .geIfPresent(WmsShipmentOrderDO::getTotalPrice, reqVO.getTotalPriceMin()) | |
| 28 | + .leIfPresent(WmsShipmentOrderDO::getTotalPrice, reqVO.getTotalPriceMax()) | |
| 29 | 29 | .eqIfPresent(WmsShipmentOrderDO::getType, reqVO.getType()) |
| 30 | 30 | .likeIfPresent(WmsShipmentOrderDO::getBizOrderNo, reqVO.getBizOrderNo()) |
| 31 | 31 | .eqIfPresent(WmsShipmentOrderDO::getCreator, reqVO.getCreator()) | ... | ... |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.wms.service.order.shipment; |
| 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.shipment.vo.detail.WmsShipmentOrderDetailSaveReqVO; | |
| 6 | 8 | import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.order.WmsShipmentOrderPageReqVO; |
| 7 | 9 | import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.order.WmsShipmentOrderSaveReqVO; |
| 8 | 10 | import cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment.WmsShipmentOrderDO; |
| ... | ... | @@ -55,6 +57,7 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService { |
| 55 | 57 | // 2.1 插入出库单 |
| 56 | 58 | WmsShipmentOrderDO order = BeanUtils.toBean(createReqVO, WmsShipmentOrderDO.class); |
| 57 | 59 | order.setStatus(WmsOrderStatusEnum.PREPARE.getStatus()); |
| 60 | + fillShipmentOrderTotal(order, createReqVO); | |
| 58 | 61 | shipmentOrderMapper.insert(order); |
| 59 | 62 | // 2.2 插入出库单明细 |
| 60 | 63 | shipmentOrderDetailService.createShipmentOrderDetailList(order.getId(), createReqVO); |
| ... | ... | @@ -71,6 +74,7 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService { |
| 71 | 74 | // 2.1 更新出库单 |
| 72 | 75 | WmsShipmentOrderDO updateObj = BeanUtils.toBean(updateReqVO, WmsShipmentOrderDO.class) |
| 73 | 76 | .setStatus(WmsOrderStatusEnum.PREPARE.getStatus()); |
| 77 | + fillShipmentOrderTotal(updateObj, updateReqVO); | |
| 74 | 78 | shipmentOrderMapper.updateById(updateObj); |
| 75 | 79 | // 2.2 更新出库单明细 |
| 76 | 80 | shipmentOrderDetailService.updateShipmentOrderDetailList(updateReqVO.getId(), updateReqVO); |
| ... | ... | @@ -160,6 +164,22 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService { |
| 160 | 164 | } |
| 161 | 165 | } |
| 162 | 166 | |
| 167 | + private void fillShipmentOrderTotal(WmsShipmentOrderDO order, WmsShipmentOrderSaveReqVO reqVO) { | |
| 168 | + BigDecimal totalQuantity = BigDecimal.ZERO; | |
| 169 | + BigDecimal totalPrice = BigDecimal.ZERO; | |
| 170 | + if (CollUtil.isNotEmpty(reqVO.getDetails())) { | |
| 171 | + for (WmsShipmentOrderDetailSaveReqVO detail : reqVO.getDetails()) { | |
| 172 | + if (detail.getQuantity() != null) { | |
| 173 | + totalQuantity = totalQuantity.add(detail.getQuantity()); | |
| 174 | + } | |
| 175 | + if (detail.getQuantity() != null && detail.getPrice() != null) { | |
| 176 | + totalPrice = totalPrice.add(detail.getQuantity().multiply(detail.getPrice())); | |
| 177 | + } | |
| 178 | + } | |
| 179 | + } | |
| 180 | + order.setTotalQuantity(totalQuantity).setTotalPrice(totalPrice); | |
| 181 | + } | |
| 182 | + | |
| 163 | 183 | private WmsShipmentOrderDO validateShipmentOrderExists(Long id) { |
| 164 | 184 | WmsShipmentOrderDO order = id == null ? null : shipmentOrderMapper.selectById(id); |
| 165 | 185 | if (order == null) { | ... | ... |
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderDetailServiceImplTest.java
| ... | ... | @@ -127,7 +127,7 @@ public class WmsShipmentOrderDetailServiceImplTest extends BaseDbUnitTest { |
| 127 | 127 | reqVO.setId(id); |
| 128 | 128 | reqVO.setSkuId(skuId); |
| 129 | 129 | reqVO.setQuantity(new BigDecimal(quantity)); |
| 130 | - reqVO.setAmount(new BigDecimal("100.00")); | |
| 130 | + reqVO.setPrice(new BigDecimal("100.00")); | |
| 131 | 131 | return reqVO; |
| 132 | 132 | } |
| 133 | 133 | |
| ... | ... | @@ -137,7 +137,7 @@ public class WmsShipmentOrderDetailServiceImplTest extends BaseDbUnitTest { |
| 137 | 137 | .skuId(skuId) |
| 138 | 138 | .warehouseId(100L) |
| 139 | 139 | .quantity(new BigDecimal(quantity)) |
| 140 | - .amount(new BigDecimal("100.00")) | |
| 140 | + .price(new BigDecimal("100.00")) | |
| 141 | 141 | .build(); |
| 142 | 142 | } |
| 143 | 143 | ... | ... |
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderServiceImplTest.java
| 1 | 1 | package cn.iocoder.yudao.module.wms.service.order.shipment; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 4 | +import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.detail.WmsShipmentOrderDetailSaveReqVO; | |
| 5 | +import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.order.WmsShipmentOrderSaveReqVO; | |
| 4 | 6 | import cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment.WmsShipmentOrderDO; |
| 5 | 7 | import cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment.WmsShipmentOrderDetailDO; |
| 6 | 8 | import cn.iocoder.yudao.module.wms.dal.mysql.order.shipment.WmsShipmentOrderDetailMapper; |
| ... | ... | @@ -21,6 +23,7 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; |
| 21 | 23 | |
| 22 | 24 | import java.math.BigDecimal; |
| 23 | 25 | import java.time.LocalDateTime; |
| 26 | +import java.util.Arrays; | |
| 24 | 27 | |
| 25 | 28 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| 26 | 29 | import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_DETAIL_REQUIRED; |
| ... | ... | @@ -53,6 +56,43 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { |
| 53 | 56 | private WmsInventoryService inventoryService; |
| 54 | 57 | |
| 55 | 58 | @Test |
| 59 | + public void testCreateShipmentOrder_calculateTotal() { | |
| 60 | + // mock 数据 | |
| 61 | + WmsShipmentOrderSaveReqVO reqVO = createShipmentOrderSaveReqVO(null, | |
| 62 | + createShipmentOrderDetailReqVO(null, 2001L, "1.50", "10.00"), | |
| 63 | + createShipmentOrderDetailReqVO(null, 2002L, "2.50", "20.00")); | |
| 64 | + | |
| 65 | + // 调用 | |
| 66 | + Long orderId = shipmentOrderService.createShipmentOrder(reqVO); | |
| 67 | + | |
| 68 | + // 断言 | |
| 69 | + WmsShipmentOrderDO dbOrder = shipmentOrderMapper.selectById(orderId); | |
| 70 | + assertNotNull(dbOrder); | |
| 71 | + assertEquals(0, new BigDecimal("4.00").compareTo(dbOrder.getTotalQuantity())); | |
| 72 | + assertEquals(0, new BigDecimal("65.00").compareTo(dbOrder.getTotalPrice())); | |
| 73 | + assertEquals(2, shipmentOrderDetailMapper.selectListByOrderId(orderId).size()); | |
| 74 | + } | |
| 75 | + | |
| 76 | + @Test | |
| 77 | + public void testUpdateShipmentOrder_calculateTotal() { | |
| 78 | + // mock 数据 | |
| 79 | + WmsShipmentOrderDO order = createShipmentOrder(100L); | |
| 80 | + shipmentOrderMapper.insert(order); | |
| 81 | + WmsShipmentOrderSaveReqVO reqVO = createShipmentOrderSaveReqVO(order.getId(), | |
| 82 | + createShipmentOrderDetailReqVO(null, 2001L, "3.00", "30.00")); | |
| 83 | + | |
| 84 | + // 调用 | |
| 85 | + shipmentOrderService.updateShipmentOrder(reqVO); | |
| 86 | + | |
| 87 | + // 断言 | |
| 88 | + WmsShipmentOrderDO dbOrder = shipmentOrderMapper.selectById(order.getId()); | |
| 89 | + assertNotNull(dbOrder); | |
| 90 | + assertEquals(0, new BigDecimal("3.00").compareTo(dbOrder.getTotalQuantity())); | |
| 91 | + assertEquals(0, new BigDecimal("90.00").compareTo(dbOrder.getTotalPrice())); | |
| 92 | + assertEquals(1, shipmentOrderDetailMapper.selectListByOrderId(order.getId()).size()); | |
| 93 | + } | |
| 94 | + | |
| 95 | + @Test | |
| 56 | 96 | public void testCompleteShipmentOrder_success() { |
| 57 | 97 | // mock 数据 |
| 58 | 98 | Long warehouseId = 100L; |
| ... | ... | @@ -143,7 +183,29 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { |
| 143 | 183 | .setStatus(WmsOrderStatusEnum.PREPARE.getStatus()) |
| 144 | 184 | .setWarehouseId(warehouseId) |
| 145 | 185 | .setTotalQuantity(new BigDecimal("2.00")) |
| 146 | - .setTotalAmount(new BigDecimal("20.00")); | |
| 186 | + .setTotalPrice(new BigDecimal("20.00")); | |
| 187 | + } | |
| 188 | + | |
| 189 | + private static WmsShipmentOrderSaveReqVO createShipmentOrderSaveReqVO(Long id, | |
| 190 | + WmsShipmentOrderDetailSaveReqVO... details) { | |
| 191 | + WmsShipmentOrderSaveReqVO reqVO = new WmsShipmentOrderSaveReqVO(); | |
| 192 | + reqVO.setId(id); | |
| 193 | + reqVO.setNo("CK202605120001"); | |
| 194 | + reqVO.setType(WmsShipmentOrderTypeEnum.SALE.getType()); | |
| 195 | + reqVO.setOrderTime(LocalDateTime.of(2026, 5, 12, 0, 0)); | |
| 196 | + reqVO.setWarehouseId(100L); | |
| 197 | + reqVO.setDetails(Arrays.asList(details)); | |
| 198 | + return reqVO; | |
| 199 | + } | |
| 200 | + | |
| 201 | + private static WmsShipmentOrderDetailSaveReqVO createShipmentOrderDetailReqVO(Long id, Long skuId, | |
| 202 | + String quantity, String price) { | |
| 203 | + WmsShipmentOrderDetailSaveReqVO reqVO = new WmsShipmentOrderDetailSaveReqVO(); | |
| 204 | + reqVO.setId(id); | |
| 205 | + reqVO.setSkuId(skuId); | |
| 206 | + reqVO.setQuantity(new BigDecimal(quantity)); | |
| 207 | + reqVO.setPrice(new BigDecimal(price)); | |
| 208 | + return reqVO; | |
| 147 | 209 | } |
| 148 | 210 | |
| 149 | 211 | private static WmsShipmentOrderDetailDO createShipmentOrderDetail(Long orderId, Long skuId, Long warehouseId) { |
| ... | ... | @@ -152,7 +214,7 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { |
| 152 | 214 | .skuId(skuId) |
| 153 | 215 | .warehouseId(warehouseId) |
| 154 | 216 | .quantity(new BigDecimal("2.00")) |
| 155 | - .amount(new BigDecimal("20.00")) | |
| 217 | + .price(new BigDecimal("20.00")) | |
| 156 | 218 | .build(); |
| 157 | 219 | } |
| 158 | 220 | ... | ... |
yudao-module-wms/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -122,7 +122,7 @@ CREATE TABLE IF NOT EXISTS "wms_shipment_order" ( |
| 122 | 122 | "remark" varchar(255) DEFAULT NULL, |
| 123 | 123 | "warehouse_id" bigint NOT NULL, |
| 124 | 124 | "total_quantity" decimal(20, 2) NOT NULL DEFAULT '0', |
| 125 | - "total_amount" decimal(10, 2) DEFAULT NULL, | |
| 125 | + "total_price" decimal(10, 2) DEFAULT NULL, | |
| 126 | 126 | "creator" varchar(64) DEFAULT '', |
| 127 | 127 | "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, |
| 128 | 128 | "updater" varchar(64) DEFAULT '', |
| ... | ... | @@ -138,7 +138,7 @@ CREATE TABLE IF NOT EXISTS "wms_shipment_order_detail" ( |
| 138 | 138 | "sku_id" bigint NOT NULL, |
| 139 | 139 | "warehouse_id" bigint NOT NULL, |
| 140 | 140 | "quantity" decimal(20, 2) NOT NULL DEFAULT '0', |
| 141 | - "amount" decimal(10, 2) DEFAULT NULL, | |
| 141 | + "price" decimal(10, 2) DEFAULT NULL, | |
| 142 | 142 | "creator" varchar(64) DEFAULT '', |
| 143 | 143 | "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, |
| 144 | 144 | "updater" varchar(64) DEFAULT '', | ... | ... |