Commit b1f836abe335401a1bd5dfa6d393c707b9bb19ef

Authored by YunaiV
1 parent 1fd112c6

✨ feat(mes): 更新盘点结果相关逻辑,添加盘点数量字段

- 修改盘点结果请求和响应对象,新增盘点数量字段并设置为必填
- 更新控制器逻辑,简化创建和更新盘点结果的处理
- 添加盘点任务行的创建和更新逻辑,确保数据一致性
- 优化错误处理,增加相关错误码
Showing 13 changed files with 239 additions and 118 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskResultController.java
... ... @@ -71,15 +71,8 @@ public class MesWmStockTakingTaskResultController {
71 71 @GetMapping("/page")
72 72 @Operation(summary = "获得盘点结果分页")
73 73 @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:query')")
74   - public CommonResult<PageResult<MesWmStockTakingTaskResultRespVO>> getStockTakingTaskResultPage(@Valid MesWmStockTakingTaskResultPageReqVO pageReqVO) {
75   - PageResult<MesWmStockTakingTaskResultDO> pageResult = stockTakingTaskResultService.getStockTakingTaskResultPage(pageReqVO);
76   - return success(new PageResult<>(buildStockTakingTaskResultRespVOList(pageResult.getList()), pageResult.getTotal()));
77   - }
78   -
79   - @GetMapping("/list")
80   - @Operation(summary = "获得盘点结果分页列表")
81   - @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:query')")
82   - public CommonResult<PageResult<MesWmStockTakingTaskResultRespVO>> getStockTakingTaskResultList(@Valid MesWmStockTakingTaskResultPageReqVO pageReqVO) {
  74 + public CommonResult<PageResult<MesWmStockTakingTaskResultRespVO>> getStockTakingTaskResultPage(
  75 + @Valid MesWmStockTakingTaskResultPageReqVO pageReqVO) {
83 76 PageResult<MesWmStockTakingTaskResultDO> pageResult = stockTakingTaskResultService.getStockTakingTaskResultPage(pageReqVO);
84 77 return success(new PageResult<>(buildStockTakingTaskResultRespVOList(pageResult.getList()), pageResult.getTotal()));
85 78 }
... ... @@ -89,9 +82,7 @@ public class MesWmStockTakingTaskResultController {
89 82 @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:update')")
90 83 @Transactional(rollbackFor = Exception.class)
91 84 public CommonResult<Long> createStockTakingTaskResult(@Valid @RequestBody MesWmStockTakingTaskResultSaveReqVO createReqVO) {
92   - MesWmStockTakingTaskResultDO result = BeanUtils.toBean(createReqVO, MesWmStockTakingTaskResultDO.class);
93   - stockTakingTaskResultService.createStockTakingTaskResult(result);
94   - return success(result.getId());
  85 + return success(stockTakingTaskResultService.createStockTakingTaskResult(createReqVO));
95 86 }
96 87  
97 88 @PutMapping("/update")
... ... @@ -99,8 +90,7 @@ public class MesWmStockTakingTaskResultController {
99 90 @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:update')")
100 91 @Transactional(rollbackFor = Exception.class)
101 92 public CommonResult<Boolean> updateStockTakingTaskResult(@Valid @RequestBody MesWmStockTakingTaskResultSaveReqVO updateReqVO) {
102   - MesWmStockTakingTaskResultDO result = BeanUtils.toBean(updateReqVO, MesWmStockTakingTaskResultDO.class);
103   - stockTakingTaskResultService.updateStockTakingTaskResult(result);
  93 + stockTakingTaskResultService.updateStockTakingTaskResult(updateReqVO);
104 94 return success(true);
105 95 }
106 96  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/result/MesWmStockTakingTaskResultSaveReqVO.java
... ... @@ -37,15 +37,17 @@ public class MesWmStockTakingTaskResultSaveReqVO {
37 37 @NotNull(message = "仓库 ID 不能为空")
38 38 private Long warehouseId;
39 39  
40   - @Schema(description = "库区 ID", example = "1")
  40 + @Schema(description = "库区 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  41 + @NotNull(message = "库区 ID 不能为空")
41 42 private Long locationId;
42 43  
43   - @Schema(description = "库位 ID", example = "1")
  44 + @Schema(description = "库位 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  45 + @NotNull(message = "库位 ID 不能为空")
44 46 private Long areaId;
45 47  
46   - @Schema(description = "差异数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.000000")
47   - @NotNull(message = "差异数量不能为空")
48   - private BigDecimal quantity;
  48 + @Schema(description = "盘点数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.000000")
  49 + @NotNull(message = "盘点数量不能为空")
  50 + private BigDecimal takingQuantity;
49 51  
50 52 @Schema(description = "备注", example = "备注")
51 53 private String remark;
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stocktaking/task/MesWmStockTakingTaskLineDO.java
... ... @@ -61,7 +61,7 @@ public class MesWmStockTakingTaskLineDO extends BaseDO {
61 61 private String batchCode;
62 62  
63 63 /**
64   - * 账面数量
  64 + * 在库数量
65 65 */
66 66 private BigDecimal quantity;
67 67 /**
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stocktaking/task/MesWmStockTakingTaskResultDO.java
... ... @@ -85,9 +85,13 @@ public class MesWmStockTakingTaskResultDO extends BaseDO {
85 85 private Long areaId;
86 86  
87 87 /**
88   - * 差异数量
  88 + * 在库数量
89 89 */
90 90 private BigDecimal quantity;
  91 + /**
  92 + * 盘点数量
  93 + */
  94 + private BigDecimal takingQuantity;
91 95  
92 96 /**
93 97 * 备注
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stocktaking/task/MesWmStockTakingTaskLineMapper.java
... ... @@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStock
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
10 10 import java.util.List;
11   -import java.util.Set;
12 11  
13 12 /**
14 13 * MES 盘点任务行 Mapper
... ... @@ -24,13 +23,6 @@ public interface MesWmStockTakingTaskLineMapper extends BaseMapperX&lt;MesWmStockTa
24 23 .orderByAsc(MesWmStockTakingTaskLineDO::getId));
25 24 }
26 25  
27   - default List<MesWmStockTakingTaskLineDO> selectListByTaskIdAndIds(Long taskId, Set<Long> ids) {
28   - return selectList(new LambdaQueryWrapperX<MesWmStockTakingTaskLineDO>()
29   - .eq(MesWmStockTakingTaskLineDO::getTaskId, taskId)
30   - .inIfPresent(MesWmStockTakingTaskLineDO::getId, ids)
31   - .orderByAsc(MesWmStockTakingTaskLineDO::getId));
32   - }
33   -
34 26 default void deleteByTaskId(Long taskId) {
35 27 delete(MesWmStockTakingTaskLineDO::getTaskId, taskId);
36 28 }
... ... @@ -41,4 +33,11 @@ public interface MesWmStockTakingTaskLineMapper extends BaseMapperX&lt;MesWmStockTa
41 33 .orderByAsc(MesWmStockTakingTaskLineDO::getId));
42 34 }
43 35  
  36 + default MesWmStockTakingTaskLineDO selectByTaskIdAndItemIdAndAreaId(Long taskId, Long itemId, Long areaId) {
  37 + return selectOne(new LambdaQueryWrapperX<MesWmStockTakingTaskLineDO>()
  38 + .eq(MesWmStockTakingTaskLineDO::getTaskId, taskId)
  39 + .eq(MesWmStockTakingTaskLineDO::getItemId, itemId)
  40 + .eqIfPresent(MesWmStockTakingTaskLineDO::getAreaId, areaId));
  41 + }
  42 +
44 43 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stocktaking/task/MesWmStockTakingTaskResultMapper.java
... ... @@ -7,8 +7,6 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.resul
7 7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
10   -import java.util.List;
11   -
12 10 /**
13 11 * MES 盘点结果 Mapper
14 12 *
... ... @@ -27,12 +25,6 @@ public interface MesWmStockTakingTaskResultMapper extends BaseMapperX&lt;MesWmStock
27 25 .orderByDesc(MesWmStockTakingTaskResultDO::getId));
28 26 }
29 27  
30   - default List<MesWmStockTakingTaskResultDO> selectListByTaskId(Long taskId) {
31   - return selectList(new LambdaQueryWrapperX<MesWmStockTakingTaskResultDO>()
32   - .eq(MesWmStockTakingTaskResultDO::getTaskId, taskId)
33   - .orderByAsc(MesWmStockTakingTaskResultDO::getId));
34   - }
35   -
36 28 default void deleteByTaskId(Long taskId) {
37 29 delete(MesWmStockTakingTaskResultDO::getTaskId, taskId);
38 30 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -485,6 +485,8 @@ public interface ErrorCodeConstants {
485 485 ErrorCode WM_STOCK_TAKING_TASK_NO_LINE = new ErrorCode(1_040_714_116, "盘点任务至少需要一条任务行");
486 486 ErrorCode WM_STOCK_TAKING_TASK_LINE_NOT_EXISTS = new ErrorCode(1_040_714_117, "盘点任务行不存在");
487 487 ErrorCode WM_STOCK_TAKING_TASK_DYNAMIC_TIME_REQUIRED = new ErrorCode(1_040_714_118, "动态盘点必须选择开始时间和结束时间");
  488 + ErrorCode WM_STOCK_TAKING_TASK_RESULT_NOT_EXISTS = new ErrorCode(1_040_714_119, "盘点结果不存在");
  489 + ErrorCode WM_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN = new ErrorCode(1_040_714_120, "该盘点清单行已有盘点记录,不能重复盘点");
488 490  
489 491 // ========== MES 仓库管理-销售出库单(1-040-714-000) ==========
490 492 ErrorCode WM_PRODUCT_SALES_NOT_EXISTS = new ErrorCode(1_040_714_000, "销售出库单不存在");
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskLineService.java
... ... @@ -3,9 +3,11 @@ package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLinePageReqVO;
5 5 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLineSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultSaveReqVO;
6 7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO;
7 8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO;
8 9  
  10 +import java.math.BigDecimal;
9 11 import java.util.List;
10 12  
11 13 /**
... ... @@ -76,4 +78,40 @@ public interface MesWmStockTakingTaskLineService {
76 78 */
77 79 void deleteStockTakingTaskLineByTaskId(Long taskId);
78 80  
  81 + /**
  82 + * 从盘点结果创建盘点任务行
  83 + *
  84 + * 注意:当盘点结果没有对应的盘点清单行时,会自动创建一个新的盘点任务行
  85 + *
  86 + * @param createReqVO 盘点结果创建信息
  87 + * @return 盘点任务行编号
  88 + */
  89 + Long createStockTakingTaskLine(MesWmStockTakingTaskResultSaveReqVO createReqVO);
  90 +
  91 + /**
  92 + * 根据 taskId + itemId + areaId 查询盘点任务行
  93 + *
  94 + * @param taskId 盘点任务编号
  95 + * @param itemId 物料编号
  96 + * @param areaId 库位编号
  97 + * @return 盘点任务行
  98 + */
  99 + MesWmStockTakingTaskLineDO getStockTakingTaskLine(Long taskId, Long itemId, Long areaId);
  100 +
  101 + /**
  102 + * 校验盘点任务行存在
  103 + *
  104 + * @param id 盘点任务行编号
  105 + * @return 盘点任务行
  106 + */
  107 + MesWmStockTakingTaskLineDO validateStockTakingTaskLineExists(Long id);
  108 +
  109 + /**
  110 + * 更新盘点任务行的盘点数量
  111 + *
  112 + * @param id 盘点任务行编号
  113 + * @param takingQuantity 盘点数量(增量)
  114 + */
  115 + void updateStockTakingTaskLineTakingQuantity(Long id, BigDecimal takingQuantity);
  116 +
79 117 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskLineServiceImpl.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 7 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO;
8 8 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLinePageReqVO;
9 9 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLineSaveReqVO;
  10 +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultSaveReqVO;
10 11 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
11 12 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.plan.MesWmStockTakingPlanParamDO;
12 13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO;
... ... @@ -121,13 +122,8 @@ public class MesWmStockTakingTaskLineServiceImpl implements MesWmStockTakingTask
121 122 stockTakingTaskLineMapper.deleteById(id);
122 123 }
123 124  
124   - /**
125   - * 校验盘点任务行是否存在
126   - *
127   - * @param id 盘点任务行编号
128   - * @return 盘点任务行
129   - */
130   - private MesWmStockTakingTaskLineDO validateStockTakingTaskLineExists(Long id) {
  125 + @Override
  126 + public MesWmStockTakingTaskLineDO validateStockTakingTaskLineExists(Long id) {
131 127 MesWmStockTakingTaskLineDO line = stockTakingTaskLineMapper.selectById(id);
132 128 if (line == null) {
133 129 throw exception(WM_STOCK_TAKING_TASK_LINE_NOT_EXISTS);
... ... @@ -172,6 +168,53 @@ public class MesWmStockTakingTaskLineServiceImpl implements MesWmStockTakingTask
172 168 stockTakingTaskLineMapper.deleteByTaskId(taskId);
173 169 }
174 170  
  171 + @Override
  172 + public MesWmStockTakingTaskLineDO getStockTakingTaskLine(Long taskId, Long itemId, Long areaId) {
  173 + return stockTakingTaskLineMapper.selectByTaskIdAndItemIdAndAreaId(taskId, itemId, areaId);
  174 + }
  175 +
  176 + @Override
  177 + public void updateStockTakingTaskLineTakingQuantity(Long id, BigDecimal takingQuantity) {
  178 + // 1. 校验盘点任务行存在
  179 + MesWmStockTakingTaskLineDO line = validateStockTakingTaskLineExists(id);
  180 + // 2. 更新盘点数量和状态
  181 + line.setTakingQuantity(takingQuantity)
  182 + .setStatus(calculateLineStatus(line.getQuantity(), takingQuantity));
  183 + stockTakingTaskLineMapper.updateById(line);
  184 + }
  185 +
  186 + @Override
  187 + public Long createStockTakingTaskLine(MesWmStockTakingTaskResultSaveReqVO createReqVO) {
  188 + MesWmStockTakingTaskLineDO line = new MesWmStockTakingTaskLineDO()
  189 + .setTaskId(createReqVO.getTaskId()).setItemId(createReqVO.getItemId()).setBatchId(createReqVO.getBatchId())
  190 + .setWarehouseId(createReqVO.getWarehouseId()).setLocationId(createReqVO.getLocationId()).setAreaId(createReqVO.getAreaId())
  191 + .setQuantity(BigDecimal.ZERO) // 账面数量默认为 0
  192 + .setTakingQuantity(createReqVO.getTakingQuantity()) // 盘点数量
  193 + .setStatus(calculateLineStatus(BigDecimal.ZERO, createReqVO.getTakingQuantity())); // 计算盈亏状态
  194 + stockTakingTaskLineMapper.insert(line);
  195 + return line.getId();
  196 + }
  197 +
  198 + /**
  199 + * 计算盘点任务行状态
  200 + *
  201 + * @param quantity 账面数量
  202 + * @param takingQuantity 盘点数量
  203 + * @return 状态
  204 + */
  205 + private Integer calculateLineStatus(BigDecimal quantity, BigDecimal takingQuantity) {
  206 + Assert.notNull(takingQuantity, "盘点数量不能为空");
  207 + Assert.notNull(quantity, "账面数量不能为空");
  208 + int compareResult = takingQuantity.compareTo(quantity);
  209 + if (compareResult > 0) {
  210 + return MesWmStockTakingTaskLineStatusEnum.GAIN.getStatus(); // 盘盈
  211 + }
  212 + if (compareResult < 0) {
  213 + return MesWmStockTakingTaskLineStatusEnum.LOSS.getStatus(); // 盘亏
  214 + }
  215 + return MesWmStockTakingTaskLineStatusEnum.NORMAL.getStatus(); // 正常
  216 + }
  217 +
175 218 /**
176 219 * 从参数列表中提取第一个匹配类型的参数 ID
177 220 *
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskResultService.java
... ... @@ -2,10 +2,9 @@ package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultPageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultSaveReqVO;
5 6 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO;
6 7  
7   -import java.util.List;
8   -
9 8 /**
10 9 * MES 盘点结果 Service 接口
11 10 *
... ... @@ -30,26 +29,19 @@ public interface MesWmStockTakingTaskResultService {
30 29 MesWmStockTakingTaskResultDO getStockTakingTaskResult(Long id);
31 30  
32 31 /**
33   - * 获得盘点结果列表
34   - *
35   - * @param taskId 盘点任务编号
36   - * @return 盘点结果列表
37   - */
38   - List<MesWmStockTakingTaskResultDO> getStockTakingTaskResultList(Long taskId);
39   -
40   - /**
41 32 * 创建盘点结果
42 33 *
43 34 * @param result 盘点结果
  35 + * @return 盘点结果编号
44 36 */
45   - void createStockTakingTaskResult(MesWmStockTakingTaskResultDO result);
  37 + Long createStockTakingTaskResult(MesWmStockTakingTaskResultSaveReqVO result);
46 38  
47 39 /**
48 40 * 更新盘点结果
49 41 *
50 42 * @param result 盘点结果
51 43 */
52   - void updateStockTakingTaskResult(MesWmStockTakingTaskResultDO result);
  44 + void updateStockTakingTaskResult(MesWmStockTakingTaskResultSaveReqVO result);
53 45  
54 46 /**
55 47 * 删除盘点结果
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskResultServiceImpl.java
1 1 package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task;
2 2  
  3 +import cn.hutool.core.util.ObjUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 6 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultPageReqVO;
  7 +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultSaveReqVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO;
5 9 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO;
6 10 import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskResultMapper;
7 11 import jakarta.annotation.Resource;
8 12 import org.springframework.stereotype.Service;
  13 +import org.springframework.transaction.annotation.Transactional;
9 14 import org.springframework.validation.annotation.Validated;
10 15  
11   -import java.util.List;
  16 +import java.math.BigDecimal;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  19 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN;
  20 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_STOCK_TAKING_TASK_RESULT_NOT_EXISTS;
12 21  
13 22 /**
14 23 * MES 盘点结果 Service 实现类
... ... @@ -22,6 +31,11 @@ public class MesWmStockTakingTaskResultServiceImpl implements MesWmStockTakingTa
22 31 @Resource
23 32 private MesWmStockTakingTaskResultMapper stockTakingTaskResultMapper;
24 33  
  34 + @Resource
  35 + private MesWmStockTakingTaskLineService stockTakingTaskLineService;
  36 + @Resource
  37 + private MesWmStockTakingTaskService stockTakingTaskService;
  38 +
25 39 @Override
26 40 public PageResult<MesWmStockTakingTaskResultDO> getStockTakingTaskResultPage(
27 41 MesWmStockTakingTaskResultPageReqVO pageReqVO) {
... ... @@ -34,23 +48,77 @@ public class MesWmStockTakingTaskResultServiceImpl implements MesWmStockTakingTa
34 48 }
35 49  
36 50 @Override
37   - public List<MesWmStockTakingTaskResultDO> getStockTakingTaskResultList(Long taskId) {
38   - return stockTakingTaskResultMapper.selectListByTaskId(taskId);
39   - }
  51 + @Transactional(rollbackFor = Exception.class)
  52 + public Long createStockTakingTaskResult(MesWmStockTakingTaskResultSaveReqVO createReqVO) {
  53 + // 1. 校验任务处于盘点中状态
  54 + stockTakingTaskService.validateStockTakingTaskExistsAndApproving(createReqVO.getTaskId());
40 55  
41   - @Override
42   - public void createStockTakingTaskResult(MesWmStockTakingTaskResultDO result) {
  56 + // 2. 确定 lineId 和账面数量
  57 + Long lineId = createReqVO.getLineId();
  58 + MesWmStockTakingTaskLineDO existingLine = null;
  59 + if (lineId == null) {
  60 + // 2.1 基于 taskId + itemId + areaId 查询已存在的 line
  61 + existingLine = stockTakingTaskLineService.getStockTakingTaskLine(
  62 + createReqVO.getTaskId(), createReqVO.getItemId(), createReqVO.getAreaId());
  63 + if (existingLine != null) {
  64 + lineId = existingLine.getId();
  65 + } else {
  66 + // 2.2 创建新的 line(注意:当盘点结果没有对应的盘点清单行时,会自动创建一个新的盘点任务行)
  67 + lineId = stockTakingTaskLineService.createStockTakingTaskLine(createReqVO);
  68 + }
  69 + } else {
  70 + // 2.3 如果传递了 lineId,从 line 中获取 quantity
  71 + existingLine = stockTakingTaskLineService.validateStockTakingTaskLineExists(lineId);
  72 + }
  73 + if (existingLine != null
  74 + && existingLine.getTakingQuantity() != null
  75 + && existingLine.getTakingQuantity().compareTo(BigDecimal.ZERO) > 0) {
  76 + throw exception(WM_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN);
  77 + }
  78 + BigDecimal quantity = existingLine != null ? existingLine.getQuantity() : BigDecimal.ZERO; // 账面数量
  79 +
  80 + // 3. 插入 result 记录
  81 + MesWmStockTakingTaskResultDO result = BeanUtils.toBean(createReqVO, MesWmStockTakingTaskResultDO.class)
  82 + .setLineId(lineId).setQuantity(ObjUtil.defaultIfNull(quantity, createReqVO.getTakingQuantity()));
43 83 stockTakingTaskResultMapper.insert(result);
  84 +
  85 + // 4. 更新 line 的盘点数量和状态
  86 + stockTakingTaskLineService.updateStockTakingTaskLineTakingQuantity(lineId, createReqVO.getTakingQuantity());
  87 + return result.getId();
44 88 }
45 89  
46 90 @Override
47   - public void updateStockTakingTaskResult(MesWmStockTakingTaskResultDO result) {
  91 + @Transactional(rollbackFor = Exception.class)
  92 + public void updateStockTakingTaskResult(MesWmStockTakingTaskResultSaveReqVO updateReqVO) {
  93 + updateReqVO.setLineId(null); // lineId 不能修改,避免误操作
  94 + // 1.1 校验记录存在
  95 + MesWmStockTakingTaskResultDO oldResult = validateStockTakingTaskResultExists(updateReqVO.getId());
  96 + // 1.2 校验任务处于盘点中状态
  97 + stockTakingTaskService.validateStockTakingTaskExistsAndApproving(oldResult.getTaskId());
  98 +
  99 + // 2. 更新 result 记录
  100 + MesWmStockTakingTaskResultDO result = BeanUtils.toBean(updateReqVO, MesWmStockTakingTaskResultDO.class);
48 101 stockTakingTaskResultMapper.updateById(result);
  102 +
  103 + // 3. 关联更新 line 的盘点数量(覆盖式更新)
  104 + stockTakingTaskLineService.updateStockTakingTaskLineTakingQuantity(
  105 + oldResult.getLineId(), updateReqVO.getTakingQuantity());
49 106 }
50 107  
51 108 @Override
  109 + @Transactional(rollbackFor = Exception.class)
52 110 public void deleteStockTakingTaskResult(Long id) {
  111 + // 1.1 校验 result 是否存在
  112 + MesWmStockTakingTaskResultDO result = validateStockTakingTaskResultExists(id);
  113 + // 1.2 校验 task 是否处于 APPROVING 状态
  114 + stockTakingTaskService.validateStockTakingTaskExistsAndApproving(result.getTaskId());
  115 +
  116 + // 2. 删除 result 记录
53 117 stockTakingTaskResultMapper.deleteById(id);
  118 +
  119 + // 3. 更新对应 line 的盘点数量和状态
  120 + stockTakingTaskLineService.updateStockTakingTaskLineTakingQuantity(
  121 + result.getLineId(), result.getTakingQuantity().negate());
54 122 }
55 123  
56 124 @Override
... ... @@ -58,4 +126,18 @@ public class MesWmStockTakingTaskResultServiceImpl implements MesWmStockTakingTa
58 126 stockTakingTaskResultMapper.deleteByTaskId(taskId);
59 127 }
60 128  
  129 + /**
  130 + * 校验盘点结果是否存在
  131 + *
  132 + * @param id 盘点结果编号
  133 + * @return 盘点结果
  134 + */
  135 + private MesWmStockTakingTaskResultDO validateStockTakingTaskResultExists(Long id) {
  136 + MesWmStockTakingTaskResultDO result = stockTakingTaskResultMapper.selectById(id);
  137 + if (result == null) {
  138 + throw exception(WM_STOCK_TAKING_TASK_RESULT_NOT_EXISTS);
  139 + }
  140 + return result;
  141 + }
  142 +
61 143 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskService.java
... ... @@ -81,6 +81,14 @@ public interface MesWmStockTakingTaskService {
81 81 MesWmStockTakingTaskDO validateStockTakingTaskExistsAndPrepare(Long id);
82 82  
83 83 /**
  84 + * 校验盘点任务存在,并且处于【盘点中】状态
  85 + *
  86 + * @param id 盘点任务编号
  87 + * @return 盘点任务
  88 + */
  89 + MesWmStockTakingTaskDO validateStockTakingTaskExistsAndApproving(Long id);
  90 +
  91 + /**
84 92 * 分页查询盘点任务
85 93 *
86 94 * @param pageReqVO 分页查询条件
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskServiceImpl.java
... ... @@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWm
9 9 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWmStockTakingTaskSaveReqVO;
10 10 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO;
11 11 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO;
12   -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO;
13 12 import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskMapper;
14   -import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingTaskLineStatusEnum;
15 13 import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingTaskStatusEnum;
16 14 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
17 15 import cn.iocoder.yudao.module.mes.service.wm.stocktaking.plan.MesWmStockTakingPlanService;
... ... @@ -23,7 +21,6 @@ import org.springframework.transaction.annotation.Transactional;
23 21 import org.springframework.validation.annotation.Validated;
24 22  
25 23 import java.math.BigDecimal;
26   -import java.time.LocalDateTime;
27 24 import java.util.List;
28 25  
29 26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -141,50 +138,20 @@ public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskServ
141 138 }
142 139 }
143 140  
144   -
145 141 @Override
146 142 @Transactional(rollbackFor = Exception.class)
147 143 public void finishStockTakingTask(Long id) {
148   - // 1.1 校验任务存在且为审批中状态
149   - MesWmStockTakingTaskDO task = validateStockTakingTaskExistsInternal(id);
150   - // 1.2 校验任务状态
151   - if (ObjUtil.notEqual(MesWmStockTakingTaskStatusEnum.APPROVING.getStatus(), task.getStatus())) {
152   - throw exception(WM_STOCK_TAKING_TASK_NOT_APPROVING);
153   - }
154   - // 1.3 获取盘点任务行
155   - List<MesWmStockTakingTaskLineDO> lines = stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id);
156   - if (CollUtil.isEmpty(lines)) {
157   - throw exception(WM_STOCK_TAKING_TASK_NO_LINE);
158   - }
159   -
160   - // 2. 生成盘点结果(仅保存差异数据)
161   - stockTakingTaskResultService.deleteStockTakingTaskResultByTaskId(id);
162   - for (MesWmStockTakingTaskLineDO line : lines) {
163   - if (MesWmStockTakingTaskLineStatusEnum.NORMAL.getStatus().equals(line.getStatus())) {
164   - continue;
165   - }
166   - stockTakingTaskResultService.createStockTakingTaskResult(MesWmStockTakingTaskResultDO.builder()
167   - .taskId(id)
168   - .lineId(line.getId())
169   - .materialStockId(line.getMaterialStockId())
170   - .itemId(line.getItemId())
171   - .batchId(line.getBatchId())
172   - .batchCode(line.getBatchCode())
173   - .warehouseId(line.getWarehouseId())
174   - .locationId(line.getLocationId())
175   - .areaId(line.getAreaId())
176   - .quantity(calculateStockTakingDifferenceQuantity(line))
177   - .remark(line.getRemark())
178   - .build());
179   - }
  144 + // 1. 校验任务存在且为审批中状态
  145 + MesWmStockTakingTaskDO task = validateStockTakingTaskExistsAndApproving(id);
180 146  
181   - // 3. 更新任务状态为已完成
182   - task.setEndTime(LocalDateTime.now());
183   - task.setStatus(MesWmStockTakingTaskStatusEnum.FINISHED.getStatus());
184   - stockTakingTaskMapper.updateById(task);
  147 + // 2. 更新任务状态为已完成
  148 + stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO().setId(id)
  149 + .setStatus(MesWmStockTakingTaskStatusEnum.FINISHED.getStatus()));
185 150  
186   - // 4. 解冻库存
  151 + // 3. 解冻库存
  152 + // TODO @芋艿:后续跟进下!
187 153 if (Boolean.TRUE.equals(task.getFrozenFlag())) {
  154 + List<MesWmStockTakingTaskLineDO> lines = stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id);
188 155 unfreezeStockTakingTaskStocks(lines);
189 156 }
190 157 }
... ... @@ -192,7 +159,7 @@ public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskServ
192 159 @Override
193 160 @Transactional(rollbackFor = Exception.class)
194 161 public void cancelStockTakingTask(Long id) {
195   - MesWmStockTakingTaskDO task = validateStockTakingTaskExistsInternal(id);
  162 + MesWmStockTakingTaskDO task = validateStockTakingTaskExists(id);
196 163 if (MesWmStockTakingTaskStatusEnum.FINISHED.getStatus().equals(task.getStatus())
197 164 || MesWmStockTakingTaskStatusEnum.CANCELED.getStatus().equals(task.getStatus())) {
198 165 throw exception(WM_STOCK_TAKING_TASK_CANNOT_CANCEL);
... ... @@ -211,15 +178,16 @@ public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskServ
211 178  
212 179 @Override
213 180 public MesWmStockTakingTaskDO validateStockTakingTaskExists(Long id) {
214   - return validateStockTakingTaskExistsInternal(id);
215   - }
216   -
217   - @Override
218   - public MesWmStockTakingTaskDO validateStockTakingTaskExistsAndPrepare(Long id) {
219 181 MesWmStockTakingTaskDO task = stockTakingTaskMapper.selectById(id);
220 182 if (task == null) {
221 183 throw exception(WM_STOCK_TAKING_TASK_NOT_EXISTS);
222 184 }
  185 + return task;
  186 + }
  187 +
  188 + @Override
  189 + public MesWmStockTakingTaskDO validateStockTakingTaskExistsAndPrepare(Long id) {
  190 + MesWmStockTakingTaskDO task = validateStockTakingTaskExists(id);
223 191 if (ObjUtil.notEqual(MesWmStockTakingTaskStatusEnum.PREPARE.getStatus(), task.getStatus())) {
224 192 throw exception(WM_STOCK_TAKING_TASK_NOT_PREPARE);
225 193 }
... ... @@ -227,6 +195,15 @@ public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskServ
227 195 }
228 196  
229 197 @Override
  198 + public MesWmStockTakingTaskDO validateStockTakingTaskExistsAndApproving(Long id) {
  199 + MesWmStockTakingTaskDO task = validateStockTakingTaskExists(id);
  200 + if (ObjUtil.notEqual(MesWmStockTakingTaskStatusEnum.APPROVING.getStatus(), task.getStatus())) {
  201 + throw exception(WM_STOCK_TAKING_TASK_NOT_APPROVING);
  202 + }
  203 + return task;
  204 + }
  205 +
  206 + @Override
230 207 public PageResult<MesWmStockTakingTaskDO> getStockTakingTaskPage(MesWmStockTakingTaskPageReqVO pageReqVO) {
231 208 return stockTakingTaskMapper.selectPage(pageReqVO);
232 209 }
... ... @@ -267,12 +244,4 @@ public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskServ
267 244 }
268 245 }
269 246  
270   - private MesWmStockTakingTaskDO validateStockTakingTaskExistsInternal(Long id) {
271   - MesWmStockTakingTaskDO task = stockTakingTaskMapper.selectById(id);
272   - if (task == null) {
273   - throw exception(WM_STOCK_TAKING_TASK_NOT_EXISTS);
274   - }
275   - return task;
276   - }
277   -
278 247 }
... ...