Commit fa5c3134accbe53381a7feda98c1440ca442f586

Authored by YunaiV
1 parent eb0819bd

✨ feat(mes): 新增批次号和出厂检验标志字段

在相关数据对象中新增批次号和出厂检验标志字段,并在服务层实现相应的逻辑校验。此变更旨在增强库存管理的灵活性和准确性。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/line/MesWmMiscIssueLineSaveReqVO.java
@@ -39,7 +39,8 @@ public class MesWmMiscIssueLineSaveReqVO { @@ -39,7 +39,8 @@ public class MesWmMiscIssueLineSaveReqVO {
39 @Schema(description = "批次号", example = "BATCH20260301") 39 @Schema(description = "批次号", example = "BATCH20260301")
40 private String batchCode; 40 private String batchCode;
41 41
42 - @Schema(description = "仓库编号", example = "1") 42 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  43 + @NotNull(message = "仓库不能为空")
43 private Long warehouseId; 44 private Long warehouseId;
44 45
45 @Schema(description = "库区编号", example = "1") 46 @Schema(description = "库区编号", example = "1")
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesLineController.java
@@ -10,9 +10,11 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesW @@ -10,9 +10,11 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesW
10 import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO; 10 import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO;
11 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; 11 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
12 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; 12 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
  13 +
13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; 14 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
14 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; 15 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
15 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; 16 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
  17 +
16 import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService; 18 import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService;
17 import io.swagger.v3.oas.annotations.Operation; 19 import io.swagger.v3.oas.annotations.Operation;
18 import io.swagger.v3.oas.annotations.Parameter; 20 import io.swagger.v3.oas.annotations.Parameter;
@@ -45,6 +47,7 @@ public class MesWmProductSalesLineController { @@ -45,6 +47,7 @@ public class MesWmProductSalesLineController {
45 @Resource 47 @Resource
46 private MesMdUnitMeasureService unitMeasureService; 48 private MesMdUnitMeasureService unitMeasureService;
47 49
  50 +
48 @PostMapping("/create") 51 @PostMapping("/create")
49 @Operation(summary = "创建销售出库单行") 52 @Operation(summary = "创建销售出库单行")
50 @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:create')") 53 @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:create')")
@@ -108,6 +111,7 @@ public class MesWmProductSalesLineController { @@ -108,6 +111,7 @@ public class MesWmProductSalesLineController {
108 MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), 111 MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
109 unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); 112 unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
110 }); 113 });
  114 +
111 }); 115 });
112 } 116 }
113 117
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/line/MesWmProductSalesLineSaveReqVO.java
@@ -28,6 +28,12 @@ public class MesWmProductSalesLineSaveReqVO { @@ -28,6 +28,12 @@ public class MesWmProductSalesLineSaveReqVO {
28 @Schema(description = "批次ID", example = "1") 28 @Schema(description = "批次ID", example = "1")
29 private Long batchId; 29 private Long batchId;
30 30
  31 + @Schema(description = "批次号", example = "B20260301001")
  32 + private String batchCode;
  33 +
  34 + @Schema(description = "是否出厂检验", example = "true")
  35 + private Boolean oqcCheckFlag;
  36 +
31 @Schema(description = "备注", example = "备注") 37 @Schema(description = "备注", example = "备注")
32 private String remark; 38 private String remark;
33 39
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesLineDO.java
@@ -2,6 +2,10 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales; @@ -2,6 +2,10 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; 4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
  8 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
5 import com.baomidou.mybatisplus.annotation.KeySequence; 9 import com.baomidou.mybatisplus.annotation.KeySequence;
6 import com.baomidou.mybatisplus.annotation.TableId; 10 import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 11 import com.baomidou.mybatisplus.annotation.TableName;
@@ -46,11 +50,21 @@ public class MesWmProductSalesLineDO extends BaseDO { @@ -46,11 +50,21 @@ public class MesWmProductSalesLineDO extends BaseDO {
46 */ 50 */
47 private BigDecimal quantity; 51 private BigDecimal quantity;
48 /** 52 /**
49 - * 批次ID 53 + * 批次 ID
  54 + *
  55 + * 关联 {@link MesWmBatchDO#getId()}
50 */ 56 */
51 private Long batchId; 57 private Long batchId;
52 /** 58 /**
  59 + * 批次号
  60 + *
  61 + * 关联 {@link MesWmBatchDO#getCode()}
  62 + */
  63 + private String batchCode;
  64 + /**
53 * 库存记录ID 65 * 库存记录ID
  66 + *
  67 + * 关联 {@link MesWmMaterialStockDO#getId()}
54 */ 68 */
55 private Long materialStockId; 69 private Long materialStockId;
56 /** 70 /**
@@ -60,13 +74,13 @@ public class MesWmProductSalesLineDO extends BaseDO { @@ -60,13 +74,13 @@ public class MesWmProductSalesLineDO extends BaseDO {
60 /** 74 /**
61 * 出厂检验单 ID 75 * 出厂检验单 ID
62 * 76 *
63 - * 关联 {@link cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO#getId()} 77 + * 关联 {@link MesQcOqcDO#getId()}
64 */ 78 */
65 private Long oqcId; 79 private Long oqcId;
66 /** 80 /**
67 * 质量状态 81 * 质量状态
68 * 82 *
69 - * 枚举 {@link cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum} 83 + * 枚举 {@link MesWmQualityStatusEnum}
70 */ 84 */
71 private Integer qualityStatus; 85 private Integer qualityStatus;
72 /** 86 /**
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueLineServiceImpl.java
@@ -46,14 +46,8 @@ public class MesWmMiscIssueLineServiceImpl implements MesWmMiscIssueLineService @@ -46,14 +46,8 @@ public class MesWmMiscIssueLineServiceImpl implements MesWmMiscIssueLineService
46 @Override 46 @Override
47 @Transactional(rollbackFor = Exception.class) 47 @Transactional(rollbackFor = Exception.class)
48 public Long createMiscIssueLine(MesWmMiscIssueLineSaveReqVO createReqVO) { 48 public Long createMiscIssueLine(MesWmMiscIssueLineSaveReqVO createReqVO) {
49 - // TODO @AI:增加 validateXXXSaveData  
50 - // 1.1 校验父单据存在且为可编辑状态  
51 - miscIssueService.validateMiscIssueEditable(createReqVO.getIssueId());  
52 - // 1.2 校验物料存在  
53 - itemService.validateItemExists(createReqVO.getItemId());  
54 - // 1.3 校验仓库、库区、库位的父子关系  
55 - warehouseAreaService.validateWarehouseAreaExists(createReqVO.getWarehouseId(),  
56 - createReqVO.getLocationId(), createReqVO.getAreaId()); 49 + // 1. 校验数据
  50 + validateMiscIssueLineSaveData(createReqVO.getIssueId(), createReqVO);
57 51
58 // 2. 新增行 52 // 2. 新增行
59 MesWmMiscIssueLineDO line = BeanUtils.toBean(createReqVO, MesWmMiscIssueLineDO.class); 53 MesWmMiscIssueLineDO line = BeanUtils.toBean(createReqVO, MesWmMiscIssueLineDO.class);
@@ -70,14 +64,8 @@ public class MesWmMiscIssueLineServiceImpl implements MesWmMiscIssueLineService @@ -70,14 +64,8 @@ public class MesWmMiscIssueLineServiceImpl implements MesWmMiscIssueLineService
70 public void updateMiscIssueLine(MesWmMiscIssueLineSaveReqVO updateReqVO) { 64 public void updateMiscIssueLine(MesWmMiscIssueLineSaveReqVO updateReqVO) {
71 // 1.1 校验存在 65 // 1.1 校验存在
72 MesWmMiscIssueLineDO line = validateAndGetMiscIssueLine(updateReqVO.getId()); 66 MesWmMiscIssueLineDO line = validateAndGetMiscIssueLine(updateReqVO.getId());
73 - // TODO @AI:增加 validateXXXSaveData  
74 - // 1.2 校验父单据存在且为可编辑状态  
75 - miscIssueService.validateMiscIssueEditable(line.getIssueId());  
76 - // 1.3 校验物料存在  
77 - itemService.validateItemExists(updateReqVO.getItemId());  
78 - // 1.4 校验仓库、库区、库位的父子关系  
79 - warehouseAreaService.validateWarehouseAreaExists(updateReqVO.getWarehouseId(),  
80 - updateReqVO.getLocationId(), updateReqVO.getAreaId()); 67 + // 1.2 校验数据
  68 + validateMiscIssueLineSaveData(line.getIssueId(), updateReqVO);
81 69
82 // 2. 更新行 70 // 2. 更新行
83 MesWmMiscIssueLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmMiscIssueLineDO.class); 71 MesWmMiscIssueLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmMiscIssueLineDO.class);
@@ -140,4 +128,14 @@ public class MesWmMiscIssueLineServiceImpl implements MesWmMiscIssueLineService @@ -140,4 +128,14 @@ public class MesWmMiscIssueLineServiceImpl implements MesWmMiscIssueLineService
140 return line; 128 return line;
141 } 129 }
142 130
  131 + private void validateMiscIssueLineSaveData(Long issueId, MesWmMiscIssueLineSaveReqVO reqVO) {
  132 + // 校验父单据存在且为可编辑状态
  133 + miscIssueService.validateMiscIssueEditable(issueId);
  134 + // 校验物料存在
  135 + itemService.validateItemExists(reqVO.getItemId());
  136 + // 校验仓库、库区、库位的父子关系
  137 + warehouseAreaService.validateWarehouseAreaExists(reqVO.getWarehouseId(),
  138 + reqVO.getLocationId(), reqVO.getAreaId());
  139 + }
  140 +
143 } 141 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.service.wm.productsales; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.service.wm.productsales;
2 2
3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 import cn.hutool.core.collection.CollUtil; 4 import cn.hutool.core.collection.CollUtil;
  5 +import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO; 7 import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO;
7 import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO; 8 import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO;
@@ -11,6 +12,8 @@ import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLi @@ -11,6 +12,8 @@ import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLi
11 import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; 12 import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum;
12 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; 13 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
13 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; 14 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  15 +import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
  16 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
14 import jakarta.annotation.Resource; 17 import jakarta.annotation.Resource;
15 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
16 import org.springframework.context.annotation.Lazy; 19 import org.springframework.context.annotation.Lazy;
@@ -42,6 +45,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe @@ -42,6 +45,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe
42 @Resource 45 @Resource
43 private MesMdItemService itemService; 46 private MesMdItemService itemService;
44 @Resource 47 @Resource
  48 + private MesWmBatchService batchService;
  49 + @Resource
45 @Lazy 50 @Lazy
46 private MesWmProductSalesService productSalesService; 51 private MesWmProductSalesService productSalesService;
47 52
@@ -49,6 +54,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe @@ -49,6 +54,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe
49 public Long createProductSalesLine(MesWmProductSalesLineSaveReqVO createReqVO) { 54 public Long createProductSalesLine(MesWmProductSalesLineSaveReqVO createReqVO) {
50 // 校验物料存在 55 // 校验物料存在
51 itemService.validateItemExists(createReqVO.getItemId()); 56 itemService.validateItemExists(createReqVO.getItemId());
  57 + // 根据 batchCode 解析 batchId
  58 + fillBatchId(createReqVO);
52 59
53 // 新增 60 // 新增
54 MesWmProductSalesLineDO line = BeanUtils.toBean(createReqVO, MesWmProductSalesLineDO.class); 61 MesWmProductSalesLineDO line = BeanUtils.toBean(createReqVO, MesWmProductSalesLineDO.class);
@@ -62,6 +69,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe @@ -62,6 +69,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe
62 validateProductSalesLineExists(updateReqVO.getId()); 69 validateProductSalesLineExists(updateReqVO.getId());
63 // 校验物料存在 70 // 校验物料存在
64 itemService.validateItemExists(updateReqVO.getItemId()); 71 itemService.validateItemExists(updateReqVO.getItemId());
  72 + // 根据 batchCode 解析 batchId
  73 + fillBatchId(updateReqVO);
65 74
66 // 更新 75 // 更新
67 MesWmProductSalesLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesLineDO.class); 76 MesWmProductSalesLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesLineDO.class);
@@ -118,6 +127,18 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe @@ -118,6 +127,18 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe
118 return line; 127 return line;
119 } 128 }
120 129
  130 + /**
  131 + * 根据 batchCode 解析 batchId
  132 + */
  133 + private void fillBatchId(MesWmProductSalesLineSaveReqVO reqVO) {
  134 + if (StrUtil.isBlank(reqVO.getBatchCode())) {
  135 + reqVO.setBatchId(null);
  136 + return;
  137 + }
  138 + MesWmBatchDO batch = batchService.getBatchByCode(reqVO.getBatchCode());
  139 + reqVO.setBatchId(batch != null ? batch.getId() : null);
  140 + }
  141 +
121 @Override 142 @Override
122 @Transactional(rollbackFor = Exception.class) 143 @Transactional(rollbackFor = Exception.class)
123 public void updateProductSalesLineWhenOqcFinish(Long id, Long oqcId, Integer checkResult) { 144 public void updateProductSalesLineWhenOqcFinish(Long id, Long oqcId, Integer checkResult) {