Commit ff8aea9dd3610085d64203500046125254666100
1 parent
c9dedd68
✨ feat(mes): 添加物料编码、名称及规格字段,更新状态管理
Showing
9 changed files
with
256 additions
and
38 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/MesWmTransferDetailController.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.controller.admin.wm.transfer; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 4 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.detail.MesWmTransferDetailRespVO; |
| 6 | 8 | import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.detail.MesWmTransferDetailSaveReqVO; |
| 9 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; | |
| 10 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; | |
| 7 | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferDetailDO; |
| 12 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; | |
| 13 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; | |
| 14 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; | |
| 15 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 16 | +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; | |
| 8 | 17 | import cn.iocoder.yudao.module.mes.service.wm.transfer.MesWmTransferDetailService; |
| 18 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | |
| 19 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; | |
| 20 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; | |
| 9 | 21 | import io.swagger.v3.oas.annotations.Operation; |
| 10 | 22 | import io.swagger.v3.oas.annotations.Parameter; |
| 11 | 23 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -15,9 +27,12 @@ import org.springframework.security.access.prepost.PreAuthorize; |
| 15 | 27 | import org.springframework.validation.annotation.Validated; |
| 16 | 28 | import org.springframework.web.bind.annotation.*; |
| 17 | 29 | |
| 30 | +import java.util.Collections; | |
| 18 | 31 | import java.util.List; |
| 32 | +import java.util.Map; | |
| 19 | 33 | |
| 20 | 34 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 35 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 21 | 36 | |
| 22 | 37 | @Tag(name = "管理后台 - MES 调拨明细") |
| 23 | 38 | @RestController |
| ... | ... | @@ -28,6 +43,21 @@ public class MesWmTransferDetailController { |
| 28 | 43 | @Resource |
| 29 | 44 | private MesWmTransferDetailService transferDetailService; |
| 30 | 45 | |
| 46 | + @Resource | |
| 47 | + private MesMdItemService itemService; | |
| 48 | + | |
| 49 | + @Resource | |
| 50 | + private MesMdUnitMeasureService unitMeasureService; | |
| 51 | + | |
| 52 | + @Resource | |
| 53 | + private MesWmWarehouseService warehouseService; | |
| 54 | + | |
| 55 | + @Resource | |
| 56 | + private MesWmWarehouseLocationService locationService; | |
| 57 | + | |
| 58 | + @Resource | |
| 59 | + private MesWmWarehouseAreaService areaService; | |
| 60 | + | |
| 31 | 61 | @PostMapping("/create") |
| 32 | 62 | @Operation(summary = "创建调拨明细") |
| 33 | 63 | @PreAuthorize("@ss.hasPermission('mes:wm-transfer:create')") |
| ... | ... | @@ -58,7 +88,10 @@ public class MesWmTransferDetailController { |
| 58 | 88 | @PreAuthorize("@ss.hasPermission('mes:wm-transfer:query')") |
| 59 | 89 | public CommonResult<MesWmTransferDetailRespVO> getTransferDetail(@RequestParam("id") Long id) { |
| 60 | 90 | MesWmTransferDetailDO detail = transferDetailService.getTransferDetail(id); |
| 61 | - return success(BeanUtils.toBean(detail, MesWmTransferDetailRespVO.class)); | |
| 91 | + if (detail == null) { | |
| 92 | + return success(null); | |
| 93 | + } | |
| 94 | + return success(buildRespVOList(Collections.singletonList(detail)).get(0)); | |
| 62 | 95 | } |
| 63 | 96 | |
| 64 | 97 | @GetMapping("/list-by-line") |
| ... | ... | @@ -68,7 +101,39 @@ public class MesWmTransferDetailController { |
| 68 | 101 | public CommonResult<List<MesWmTransferDetailRespVO>> getTransferDetailListByLineId( |
| 69 | 102 | @RequestParam("lineId") Long lineId) { |
| 70 | 103 | List<MesWmTransferDetailDO> list = transferDetailService.getTransferDetailListByLineId(lineId); |
| 71 | - return success(BeanUtils.toBean(list, MesWmTransferDetailRespVO.class)); | |
| 104 | + return success(buildRespVOList(list)); | |
| 105 | + } | |
| 106 | + | |
| 107 | + // ==================== 拼接 VO ==================== | |
| 108 | + | |
| 109 | + private List<MesWmTransferDetailRespVO> buildRespVOList(List<MesWmTransferDetailDO> list) { | |
| 110 | + if (CollUtil.isEmpty(list)) { | |
| 111 | + return Collections.emptyList(); | |
| 112 | + } | |
| 113 | + // 查询相关数据 | |
| 114 | + Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesWmTransferDetailDO::getItemId)); | |
| 115 | + Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap( | |
| 116 | + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); | |
| 117 | + Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( | |
| 118 | + convertSet(list, MesWmTransferDetailDO::getToWarehouseId)); | |
| 119 | + Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap( | |
| 120 | + convertSet(list, MesWmTransferDetailDO::getToLocationId)); | |
| 121 | + Map<Long, MesWmWarehouseAreaDO> areaMap = areaService.getWarehouseAreaMap( | |
| 122 | + convertSet(list, MesWmTransferDetailDO::getToAreaId)); | |
| 123 | + // 拼接数据 | |
| 124 | + return BeanUtils.toBean(list, MesWmTransferDetailRespVO.class, vo -> { | |
| 125 | + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { | |
| 126 | + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); | |
| 127 | + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), | |
| 128 | + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); | |
| 129 | + }); | |
| 130 | + MapUtils.findAndThen(warehouseMap, vo.getToWarehouseId(), | |
| 131 | + warehouse -> vo.setToWarehouseName(warehouse.getName())); | |
| 132 | + MapUtils.findAndThen(locationMap, vo.getToLocationId(), | |
| 133 | + location -> vo.setToLocationName(location.getName())); | |
| 134 | + MapUtils.findAndThen(areaMap, vo.getToAreaId(), | |
| 135 | + area -> vo.setToAreaName(area.getName())); | |
| 136 | + }); | |
| 72 | 137 | } |
| 73 | 138 | |
| 74 | 139 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/MesWmTransferLineController.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.controller.admin.wm.transfer; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 4 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.line.MesWmTransferLineRespVO; |
| 6 | 8 | import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.line.MesWmTransferLineSaveReqVO; |
| 9 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; | |
| 10 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; | |
| 7 | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO; |
| 12 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; | |
| 13 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; | |
| 14 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; | |
| 15 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 16 | +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; | |
| 8 | 17 | import cn.iocoder.yudao.module.mes.service.wm.transfer.MesWmTransferLineService; |
| 18 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | |
| 19 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; | |
| 20 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; | |
| 9 | 21 | import io.swagger.v3.oas.annotations.Operation; |
| 10 | 22 | import io.swagger.v3.oas.annotations.Parameter; |
| 11 | 23 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -15,9 +27,12 @@ import org.springframework.security.access.prepost.PreAuthorize; |
| 15 | 27 | import org.springframework.validation.annotation.Validated; |
| 16 | 28 | import org.springframework.web.bind.annotation.*; |
| 17 | 29 | |
| 30 | +import java.util.Collections; | |
| 18 | 31 | import java.util.List; |
| 32 | +import java.util.Map; | |
| 19 | 33 | |
| 20 | 34 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 35 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 21 | 36 | |
| 22 | 37 | @Tag(name = "管理后台 - MES 转移单行") |
| 23 | 38 | @RestController |
| ... | ... | @@ -28,6 +43,21 @@ public class MesWmTransferLineController { |
| 28 | 43 | @Resource |
| 29 | 44 | private MesWmTransferLineService transferLineService; |
| 30 | 45 | |
| 46 | + @Resource | |
| 47 | + private MesMdItemService itemService; | |
| 48 | + | |
| 49 | + @Resource | |
| 50 | + private MesMdUnitMeasureService unitMeasureService; | |
| 51 | + | |
| 52 | + @Resource | |
| 53 | + private MesWmWarehouseService warehouseService; | |
| 54 | + | |
| 55 | + @Resource | |
| 56 | + private MesWmWarehouseLocationService locationService; | |
| 57 | + | |
| 58 | + @Resource | |
| 59 | + private MesWmWarehouseAreaService areaService; | |
| 60 | + | |
| 31 | 61 | @PostMapping("/create") |
| 32 | 62 | @Operation(summary = "创建转移单行") |
| 33 | 63 | @PreAuthorize("@ss.hasPermission('mes:wm-transfer:create')") |
| ... | ... | @@ -58,7 +88,10 @@ public class MesWmTransferLineController { |
| 58 | 88 | @PreAuthorize("@ss.hasPermission('mes:wm-transfer:query')") |
| 59 | 89 | public CommonResult<MesWmTransferLineRespVO> getTransferLine(@RequestParam("id") Long id) { |
| 60 | 90 | MesWmTransferLineDO line = transferLineService.getTransferLine(id); |
| 61 | - return success(BeanUtils.toBean(line, MesWmTransferLineRespVO.class)); | |
| 91 | + if (line == null) { | |
| 92 | + return success(null); | |
| 93 | + } | |
| 94 | + return success(buildRespVOList(Collections.singletonList(line)).get(0)); | |
| 62 | 95 | } |
| 63 | 96 | |
| 64 | 97 | @GetMapping("/list") |
| ... | ... | @@ -67,7 +100,39 @@ public class MesWmTransferLineController { |
| 67 | 100 | @PreAuthorize("@ss.hasPermission('mes:wm-transfer:query')") |
| 68 | 101 | public CommonResult<List<MesWmTransferLineRespVO>> getTransferLineList(@RequestParam("transferId") Long transferId) { |
| 69 | 102 | List<MesWmTransferLineDO> list = transferLineService.getTransferLineListByTransferId(transferId); |
| 70 | - return success(BeanUtils.toBean(list, MesWmTransferLineRespVO.class)); | |
| 103 | + return success(buildRespVOList(list)); | |
| 104 | + } | |
| 105 | + | |
| 106 | + // ==================== 拼接 VO ==================== | |
| 107 | + | |
| 108 | + private List<MesWmTransferLineRespVO> buildRespVOList(List<MesWmTransferLineDO> list) { | |
| 109 | + if (CollUtil.isEmpty(list)) { | |
| 110 | + return Collections.emptyList(); | |
| 111 | + } | |
| 112 | + // 查询相关数据 | |
| 113 | + Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesWmTransferLineDO::getItemId)); | |
| 114 | + Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap( | |
| 115 | + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); | |
| 116 | + Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( | |
| 117 | + convertSet(list, MesWmTransferLineDO::getFromWarehouseId)); | |
| 118 | + Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap( | |
| 119 | + convertSet(list, MesWmTransferLineDO::getFromLocationId)); | |
| 120 | + Map<Long, MesWmWarehouseAreaDO> areaMap = areaService.getWarehouseAreaMap( | |
| 121 | + convertSet(list, MesWmTransferLineDO::getFromAreaId)); | |
| 122 | + // 拼接数据 | |
| 123 | + return BeanUtils.toBean(list, MesWmTransferLineRespVO.class, vo -> { | |
| 124 | + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { | |
| 125 | + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); | |
| 126 | + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), | |
| 127 | + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); | |
| 128 | + }); | |
| 129 | + MapUtils.findAndThen(warehouseMap, vo.getFromWarehouseId(), | |
| 130 | + warehouse -> vo.setFromWarehouseName(warehouse.getName())); | |
| 131 | + MapUtils.findAndThen(locationMap, vo.getFromLocationId(), | |
| 132 | + location -> vo.setFromLocationName(location.getName())); | |
| 133 | + MapUtils.findAndThen(areaMap, vo.getFromAreaId(), | |
| 134 | + area -> vo.setFromAreaName(area.getName())); | |
| 135 | + }); | |
| 71 | 136 | } |
| 72 | 137 | |
| 73 | 138 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/vo/detail/MesWmTransferDetailRespVO.java
| ... | ... | @@ -20,21 +20,37 @@ public class MesWmTransferDetailRespVO { |
| 20 | 20 | |
| 21 | 21 | @Schema(description = "物料编号", example = "1") |
| 22 | 22 | private Long itemId; |
| 23 | + @Schema(description = "物料编码") | |
| 24 | + private String itemCode; | |
| 25 | + @Schema(description = "物料名称") | |
| 26 | + private String itemName; | |
| 27 | + @Schema(description = "规格型号") | |
| 28 | + private String specification; | |
| 29 | + @Schema(description = "单位名称") | |
| 30 | + private String unitMeasureName; | |
| 23 | 31 | |
| 24 | 32 | @Schema(description = "上架数量", example = "100") |
| 25 | 33 | private BigDecimal quantity; |
| 26 | 34 | |
| 27 | 35 | @Schema(description = "批次编号", example = "1") |
| 28 | 36 | private Long batchId; |
| 37 | + @Schema(description = "批次号") | |
| 38 | + private String batchCode; | |
| 29 | 39 | |
| 30 | 40 | @Schema(description = "移入仓库编号", example = "1") |
| 31 | 41 | private Long toWarehouseId; |
| 42 | + @Schema(description = "移入仓库名称") | |
| 43 | + private String toWarehouseName; | |
| 32 | 44 | |
| 33 | 45 | @Schema(description = "移入库区编号", example = "1") |
| 34 | 46 | private Long toLocationId; |
| 47 | + @Schema(description = "移入库区名称") | |
| 48 | + private String toLocationName; | |
| 35 | 49 | |
| 36 | 50 | @Schema(description = "移入库位编号", example = "1") |
| 37 | 51 | private Long toAreaId; |
| 52 | + @Schema(description = "移入库位名称") | |
| 53 | + private String toAreaName; | |
| 38 | 54 | |
| 39 | 55 | @Schema(description = "备注", example = "备注信息") |
| 40 | 56 | private String remark; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/vo/detail/MesWmTransferDetailSaveReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.detail; |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.DecimalMin; | |
| 5 | +import jakarta.validation.constraints.NotNull; | |
| 4 | 6 | import lombok.Data; |
| 5 | 7 | |
| 6 | 8 | import java.math.BigDecimal; |
| ... | ... | @@ -12,28 +14,36 @@ public class MesWmTransferDetailSaveReqVO { |
| 12 | 14 | @Schema(description = "编号", example = "1") |
| 13 | 15 | private Long id; |
| 14 | 16 | |
| 15 | - @Schema(description = "转移单行编号", example = "1") | |
| 17 | + @Schema(description = "转移单行编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 18 | + @NotNull(message = "转移单行编号不能为空") | |
| 16 | 19 | private Long lineId; |
| 17 | 20 | |
| 18 | - @Schema(description = "转移单编号", example = "1") | |
| 21 | + @Schema(description = "转移单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 22 | + @NotNull(message = "转移单编号不能为空") | |
| 19 | 23 | private Long transferId; |
| 20 | 24 | |
| 21 | - @Schema(description = "物料编号", example = "1") | |
| 25 | + @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 26 | + @NotNull(message = "物料编号不能为空") | |
| 22 | 27 | private Long itemId; |
| 23 | 28 | |
| 24 | - @Schema(description = "上架数量", example = "100") | |
| 29 | + @Schema(description = "上架数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | |
| 30 | + @NotNull(message = "上架数量不能为空") | |
| 31 | + @DecimalMin(value = "0.01", message = "上架数量必须大于 0") | |
| 25 | 32 | private BigDecimal quantity; |
| 26 | 33 | |
| 27 | 34 | @Schema(description = "批次编号", example = "1") |
| 28 | 35 | private Long batchId; |
| 29 | 36 | |
| 30 | - @Schema(description = "移入仓库编号", example = "1") | |
| 37 | + @Schema(description = "移入仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 38 | + @NotNull(message = "移入仓库编号不能为空") | |
| 31 | 39 | private Long toWarehouseId; |
| 32 | 40 | |
| 33 | - @Schema(description = "移入库区编号", example = "1") | |
| 41 | + @Schema(description = "移入库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 42 | + @NotNull(message = "移入库区编号不能为空") | |
| 34 | 43 | private Long toLocationId; |
| 35 | 44 | |
| 36 | - @Schema(description = "移入库位编号", example = "1") | |
| 45 | + @Schema(description = "移入库位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 46 | + @NotNull(message = "移入库位编号不能为空") | |
| 37 | 47 | private Long toAreaId; |
| 38 | 48 | |
| 39 | 49 | @Schema(description = "备注", example = "备注信息") | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/vo/line/MesWmTransferLineRespVO.java
| ... | ... | @@ -20,21 +20,37 @@ public class MesWmTransferLineRespVO { |
| 20 | 20 | |
| 21 | 21 | @Schema(description = "物料编号", example = "1") |
| 22 | 22 | private Long itemId; |
| 23 | + @Schema(description = "物料编码") | |
| 24 | + private String itemCode; | |
| 25 | + @Schema(description = "物料名称") | |
| 26 | + private String itemName; | |
| 27 | + @Schema(description = "规格型号") | |
| 28 | + private String specification; | |
| 29 | + @Schema(description = "单位名称") | |
| 30 | + private String unitMeasureName; | |
| 23 | 31 | |
| 24 | 32 | @Schema(description = "转移数量", example = "100") |
| 25 | 33 | private BigDecimal quantity; |
| 26 | 34 | |
| 27 | 35 | @Schema(description = "批次编号", example = "1") |
| 28 | 36 | private Long batchId; |
| 37 | + @Schema(description = "批次号") | |
| 38 | + private String batchCode; | |
| 29 | 39 | |
| 30 | 40 | @Schema(description = "移出仓库编号", example = "1") |
| 31 | 41 | private Long fromWarehouseId; |
| 42 | + @Schema(description = "移出仓库名称") | |
| 43 | + private String fromWarehouseName; | |
| 32 | 44 | |
| 33 | 45 | @Schema(description = "移出库区编号", example = "1") |
| 34 | 46 | private Long fromLocationId; |
| 47 | + @Schema(description = "移出库区名称") | |
| 48 | + private String fromLocationName; | |
| 35 | 49 | |
| 36 | 50 | @Schema(description = "移出库位编号", example = "1") |
| 37 | 51 | private Long fromAreaId; |
| 52 | + @Schema(description = "移出库位名称") | |
| 53 | + private String fromAreaName; | |
| 38 | 54 | |
| 39 | 55 | @Schema(description = "备注", example = "备注信息") |
| 40 | 56 | private String remark; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/vo/line/MesWmTransferLineSaveReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.line; |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.DecimalMin; | |
| 5 | +import jakarta.validation.constraints.NotNull; | |
| 4 | 6 | import lombok.Data; |
| 5 | 7 | |
| 6 | 8 | import java.math.BigDecimal; |
| ... | ... | @@ -12,34 +14,35 @@ public class MesWmTransferLineSaveReqVO { |
| 12 | 14 | @Schema(description = "编号", example = "1") |
| 13 | 15 | private Long id; |
| 14 | 16 | |
| 15 | - @Schema(description = "转移单编号", example = "1") | |
| 16 | - // TODO @AI:不能为空 | |
| 17 | + @Schema(description = "转移单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 18 | + @NotNull(message = "转移单编号不能为空") | |
| 17 | 19 | private Long transferId; |
| 18 | 20 | |
| 19 | 21 | @Schema(description = "库存记录编号", example = "1") |
| 20 | 22 | private Long materialStockId; |
| 21 | 23 | |
| 22 | - @Schema(description = "物料编号", example = "1") | |
| 23 | - // TODO @AI:不能为空 | |
| 24 | + @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 25 | + @NotNull(message = "物料编号不能为空") | |
| 24 | 26 | private Long itemId; |
| 25 | 27 | |
| 26 | - @Schema(description = "转移数量", example = "100") | |
| 27 | - // TODO @AI:数量不能为空,且要大于 0 | |
| 28 | + @Schema(description = "转移数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | |
| 29 | + @NotNull(message = "转移数量不能为空") | |
| 30 | + @DecimalMin(value = "0.01", message = "转移数量必须大于 0") | |
| 28 | 31 | private BigDecimal quantity; |
| 29 | 32 | |
| 30 | 33 | @Schema(description = "批次编号", example = "1") |
| 31 | 34 | private Long batchId; |
| 32 | 35 | |
| 33 | - @Schema(description = "移出仓库编号", example = "1") | |
| 34 | - // TODO @AI:不能为空 | |
| 36 | + @Schema(description = "移出仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 37 | + @NotNull(message = "移出仓库编号不能为空") | |
| 35 | 38 | private Long fromWarehouseId; |
| 36 | 39 | |
| 37 | - @Schema(description = "移出库区编号", example = "1") | |
| 38 | - // TODO @AI:不能为空 | |
| 40 | + @Schema(description = "移出库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 41 | + @NotNull(message = "移出库区编号不能为空") | |
| 39 | 42 | private Long fromLocationId; |
| 40 | 43 | |
| 41 | - @Schema(description = "移出库位编号", example = "1") | |
| 42 | - // TODO @AI:不能为空 | |
| 44 | + @Schema(description = "移出库位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 45 | + @NotNull(message = "移出库位编号不能为空") | |
| 43 | 46 | private Long fromAreaId; |
| 44 | 47 | |
| 45 | 48 | @Schema(description = "备注", example = "备注信息") | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| ... | ... | @@ -401,13 +401,14 @@ public interface ErrorCodeConstants { |
| 401 | 401 | ErrorCode WM_TRANSFER_CODE_DUPLICATE = new ErrorCode(1_040_710_002, "转移单编号已存在"); |
| 402 | 402 | ErrorCode WM_TRANSFER_NOT_DRAFT = new ErrorCode(1_040_710_003, "只有草稿状态的转移单才可操作"); |
| 403 | 403 | ErrorCode WM_TRANSFER_NOT_CONFIRMED = new ErrorCode(1_040_710_004, "只有待确认状态的转移单才可执行确认"); |
| 404 | - ErrorCode WM_TRANSFER_NOT_UNSTOCK = new ErrorCode(1_040_710_005, "只有待上架状态的转移单才可执行上架"); | |
| 405 | - ErrorCode WM_TRANSFER_NOT_UNEXECUTE = new ErrorCode(1_040_710_006, "只有待执行状态的转移单才可完成"); | |
| 404 | + ErrorCode WM_TRANSFER_NOT_APPROVING = new ErrorCode(1_040_710_005, "只有待上架状态的转移单才可执行上架"); | |
| 405 | + ErrorCode WM_TRANSFER_NOT_APPROVED = new ErrorCode(1_040_710_006, "只有待执行状态的转移单才可完成"); | |
| 406 | 406 | ErrorCode WM_TRANSFER_ALREADY_FINISHED = new ErrorCode(1_040_710_007, "转移单已完成或已取消,无法继续操作"); |
| 407 | 407 | ErrorCode WM_TRANSFER_NO_LINE = new ErrorCode(1_040_710_008, "转移单至少需要一条行数据"); |
| 408 | 408 | ErrorCode WM_TRANSFER_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_710_009, "转移单行数量与明细数量不一致"); |
| 409 | 409 | ErrorCode WM_TRANSFER_LINE_NOT_EXISTS = new ErrorCode(1_040_710_100, "转移单行不存在"); |
| 410 | 410 | ErrorCode WM_TRANSFER_DETAIL_NOT_EXISTS = new ErrorCode(1_040_710_200, "调拨明细不存在"); |
| 411 | + ErrorCode WM_TRANSFER_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_710_201, "调拨明细总数量不能超过调拨单行数量"); | |
| 411 | 412 | |
| 412 | 413 | // ========== MES 仓库管理-生产退料单(1-040-711-000) ========== |
| 413 | 414 | ErrorCode WM_RETURN_ISSUE_NOT_EXISTS = new ErrorCode(1_040_710_000, "生产退料单不存在"); | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransferStatusEnum.java
| ... | ... | @@ -30,20 +30,18 @@ public enum MesWmTransferStatusEnum implements ArrayValuable<Integer> { |
| 30 | 30 | * 对应方法:{@link MesWmTransferService#submitTransfer(Long)} |
| 31 | 31 | */ |
| 32 | 32 | UNCONFIRMED(MesOrderStatusConstants.CONFIRMED, "待确认"), |
| 33 | - // TODO @AI:前后端,要不都改成 APPROVING | |
| 34 | 33 | /** |
| 35 | 34 | * 待上架 |
| 36 | 35 | * |
| 37 | 36 | * 对应方法:{@link MesWmTransferService#submitTransfer(Long)}、{@link MesWmTransferService#confirmTransfer(Long)} |
| 38 | 37 | */ |
| 39 | - UNSTOCK(MesOrderStatusConstants.APPROVING, "待上架"), | |
| 40 | - // TODO @AI:前后端,要不都改成 APPROVED | |
| 38 | + APPROVING(MesOrderStatusConstants.APPROVING, "待上架"), | |
| 41 | 39 | /** |
| 42 | 40 | * 待执行 |
| 43 | 41 | * |
| 44 | 42 | * 对应方法:{@link MesWmTransferService#stockTransfer(Long)} |
| 45 | 43 | */ |
| 46 | - UNEXECUTE(MesOrderStatusConstants.APPROVED, "待执行"), | |
| 44 | + APPROVED(MesOrderStatusConstants.APPROVED, "待执行"), | |
| 47 | 45 | /** |
| 48 | 46 | * 已完成 |
| 49 | 47 | * | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transfer/MesWmTransferDetailServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.wm.transfer; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 4 | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.detail.MesWmTransferDetailSaveReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferDetailDO; |
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO; | |
| 6 | 8 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.transfer.MesWmTransferDetailMapper; |
| 9 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | |
| 7 | 10 | import jakarta.annotation.Resource; |
| 8 | 11 | import org.springframework.context.annotation.Lazy; |
| 9 | 12 | import org.springframework.stereotype.Service; |
| 10 | 13 | import org.springframework.validation.annotation.Validated; |
| 11 | 14 | |
| 15 | +import java.math.BigDecimal; | |
| 12 | 16 | import java.util.List; |
| 13 | 17 | |
| 14 | 18 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 15 | 19 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_TRANSFER_DETAIL_NOT_EXISTS; |
| 20 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_TRANSFER_DETAIL_QUANTITY_EXCEED; | |
| 16 | 21 | |
| 17 | 22 | /** |
| 18 | 23 | * MES 调拨明细 Service 实现类 |
| ... | ... | @@ -28,12 +33,21 @@ public class MesWmTransferDetailServiceImpl implements MesWmTransferDetailServic |
| 28 | 33 | @Lazy |
| 29 | 34 | private MesWmTransferLineService transferLineService; |
| 30 | 35 | |
| 36 | + @Resource | |
| 37 | + private MesWmWarehouseAreaService warehouseAreaService; | |
| 38 | + | |
| 31 | 39 | @Override |
| 32 | 40 | public Long createTransferDetail(MesWmTransferDetailSaveReqVO createReqVO) { |
| 33 | - transferLineService.validateTransferLineExists(createReqVO.getLineId()); | |
| 34 | - // DONE @AI:当前先保留行存在校验,其他关联校验需结合上架业务与库位规则统一设计,暂不在本轮 TODO 修复中扩展 | |
| 35 | - // TODO @AI:位置相关的几个校验; | |
| 36 | - | |
| 41 | + // 校验父数据存在 | |
| 42 | + MesWmTransferLineDO line = transferLineService.validateTransferLineExists(createReqVO.getLineId()); | |
| 43 | + // 校验仓库、库区、库位的关联关系 | |
| 44 | + warehouseAreaService.validateWarehouseAreaExists( | |
| 45 | + createReqVO.getToWarehouseId(), createReqVO.getToLocationId(), createReqVO.getToAreaId()); | |
| 46 | + // 校验明细总数量不超过行数量 | |
| 47 | + validateDetailQuantityNotExceed(createReqVO.getLineId(), createReqVO.getQuantity(), null, line); | |
| 48 | + // TODO @芋艿:不能混货 | |
| 49 | + | |
| 50 | + // 插入 | |
| 37 | 51 | MesWmTransferDetailDO detail = BeanUtils.toBean(createReqVO, MesWmTransferDetailDO.class); |
| 38 | 52 | transferDetailMapper.insert(detail); |
| 39 | 53 | return detail.getId(); |
| ... | ... | @@ -41,19 +55,27 @@ public class MesWmTransferDetailServiceImpl implements MesWmTransferDetailServic |
| 41 | 55 | |
| 42 | 56 | @Override |
| 43 | 57 | public void updateTransferDetail(MesWmTransferDetailSaveReqVO updateReqVO) { |
| 58 | + // 校验存在 | |
| 44 | 59 | validateTransferDetailExists(updateReqVO.getId()); |
| 45 | - transferLineService.validateTransferLineExists(updateReqVO.getLineId()); | |
| 46 | - // DONE @AI:当前先保留行存在校验,其他关联校验需结合上架业务与库位规则统一设计,暂不在本轮 TODO 修复中扩展 | |
| 47 | - // TODO @AI:位置相关的几个校验; | |
| 48 | - | |
| 60 | + // 校验父数据存在 | |
| 61 | + MesWmTransferLineDO line = transferLineService.validateTransferLineExists(updateReqVO.getLineId()); | |
| 62 | + // 校验仓库、库区、库位的关联关系 | |
| 63 | + warehouseAreaService.validateWarehouseAreaExists( | |
| 64 | + updateReqVO.getToWarehouseId(), updateReqVO.getToLocationId(), updateReqVO.getToAreaId()); | |
| 65 | + // 校验明细总数量不超过行数量(排除自身) | |
| 66 | + validateDetailQuantityNotExceed(updateReqVO.getLineId(), updateReqVO.getQuantity(), updateReqVO.getId(), line); | |
| 67 | + // TODO @芋艿:不能混货 | |
| 68 | + | |
| 69 | + // 更新 | |
| 49 | 70 | MesWmTransferDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmTransferDetailDO.class); |
| 50 | 71 | transferDetailMapper.updateById(updateObj); |
| 51 | 72 | } |
| 52 | 73 | |
| 53 | 74 | @Override |
| 54 | 75 | public void deleteTransferDetail(Long id) { |
| 55 | - // DONE @AI:当前先保留行存在校验,其他关联校验需结合上架业务与库位规则统一设计,暂不在本轮 TODO 修复中扩展 | |
| 76 | + // 校验存在 | |
| 56 | 77 | validateTransferDetailExists(id); |
| 78 | + // 删除 | |
| 57 | 79 | transferDetailMapper.deleteById(id); |
| 58 | 80 | } |
| 59 | 81 | |
| ... | ... | @@ -84,4 +106,26 @@ public class MesWmTransferDetailServiceImpl implements MesWmTransferDetailServic |
| 84 | 106 | } |
| 85 | 107 | } |
| 86 | 108 | |
| 109 | + /** | |
| 110 | + * 校验明细总数量不超过行数量 | |
| 111 | + * | |
| 112 | + * @param lineId 行 ID | |
| 113 | + * @param newQuantity 本次新增/修改的数量 | |
| 114 | + * @param excludeDetailId 排除的明细 ID(更新时排除自身,新增时传 null) | |
| 115 | + * @param line 调拨单行 | |
| 116 | + */ | |
| 117 | + private void validateDetailQuantityNotExceed(Long lineId, BigDecimal newQuantity, | |
| 118 | + Long excludeDetailId, MesWmTransferLineDO line) { | |
| 119 | + // 计算已有明细总数量(排除自身) | |
| 120 | + List<MesWmTransferDetailDO> details = transferDetailMapper.selectListByLineId(lineId); | |
| 121 | + BigDecimal existingTotal = CollectionUtils.getSumValue(details, | |
| 122 | + detail -> excludeDetailId != null && excludeDetailId.equals(detail.getId()) | |
| 123 | + ? BigDecimal.ZERO : detail.getQuantity(), | |
| 124 | + BigDecimal::add, BigDecimal.ZERO); | |
| 125 | + // 校验:已有 + 本次 <= 行数量 | |
| 126 | + if (existingTotal.add(newQuantity).compareTo(line.getQuantity()) > 0) { | |
| 127 | + throw exception(WM_TRANSFER_DETAIL_QUANTITY_EXCEED); | |
| 128 | + } | |
| 129 | + } | |
| 130 | + | |
| 87 | 131 | } | ... | ... |