Commit c62f0e67fb80eb0a2540968b2ff0df706f2acdb5
1 parent
aa5e1618
feat(mes): 支持盘点任务的动态时间过滤:
1. 新增动态盘点时间过滤功能 2. 重构盘点任务流程 3. 代码优化 4. 前端适配
Showing
15 changed files
with
723 additions
and
36 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockListReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import java.time.LocalDateTime; | ||
| 7 | + | ||
| 8 | +@Schema(description = "管理后台 - 物料库存查询 Request VO") | ||
| 9 | +@Data | ||
| 10 | +public class MesWmMaterialStockListReqVO { | ||
| 11 | + | ||
| 12 | + @Schema(description = "仓库编号") | ||
| 13 | + private Long warehouseId; | ||
| 14 | + | ||
| 15 | + @Schema(description = "库区编号") | ||
| 16 | + private Long locationId; | ||
| 17 | + | ||
| 18 | + @Schema(description = "库位编号") | ||
| 19 | + private Long areaId; | ||
| 20 | + | ||
| 21 | + @Schema(description = "物料编号") | ||
| 22 | + private Long itemId; | ||
| 23 | + | ||
| 24 | + @Schema(description = "批次编号") | ||
| 25 | + private Long batchId; | ||
| 26 | + // TODO @芋艿:后面看看,要不要 batchCode | ||
| 27 | + | ||
| 28 | + @Schema(description = "开始时间(动态盘点用)") | ||
| 29 | + private LocalDateTime startTime; | ||
| 30 | + | ||
| 31 | + @Schema(description = "结束时间(动态盘点用)") | ||
| 32 | + private LocalDateTime endTime; | ||
| 33 | + | ||
| 34 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskController.java
| @@ -98,9 +98,10 @@ public class MesWmStockTakingTaskController { | @@ -98,9 +98,10 @@ public class MesWmStockTakingTaskController { | ||
| 98 | 98 | ||
| 99 | @PutMapping("/submit") | 99 | @PutMapping("/submit") |
| 100 | @Operation(summary = "提交盘点任务") | 100 | @Operation(summary = "提交盘点任务") |
| 101 | + @Parameter(name = "id", description = "编号", required = true) | ||
| 101 | @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:update')") | 102 | @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:update')") |
| 102 | - public CommonResult<Boolean> submitStockTakingTask(@Valid @RequestBody MesWmStockTakingTaskSubmitReqVO reqVO) { | ||
| 103 | - stockTakingTaskService.submitStockTakingTask(reqVO.getId()); | 103 | + public CommonResult<Boolean> submitStockTakingTask(@RequestParam("id") Long id) { |
| 104 | + stockTakingTaskService.submitStockTakingTask(id); | ||
| 104 | return success(true); | 105 | return success(true); |
| 105 | } | 106 | } |
| 106 | 107 | ||
| @@ -136,14 +137,6 @@ public class MesWmStockTakingTaskController { | @@ -136,14 +137,6 @@ public class MesWmStockTakingTaskController { | ||
| 136 | buildTaskRespVOList(pageResult.getList())); | 137 | buildTaskRespVOList(pageResult.getList())); |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | - @PutMapping("/start") | ||
| 140 | - @Operation(summary = "开始盘点任务") | ||
| 141 | - @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:update')") | ||
| 142 | - public CommonResult<Boolean> startStockTakingTask(@Valid @RequestBody MesWmStockTakingTaskStartReqVO reqVO) { | ||
| 143 | - stockTakingTaskService.startStockTakingTask(reqVO.getId()); | ||
| 144 | - return success(true); | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | @PutMapping("/finish") | 140 | @PutMapping("/finish") |
| 148 | @Operation(summary = "完成盘点任务") | 141 | @Operation(summary = "完成盘点任务") |
| 149 | @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:finish')") | 142 | @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:finish')") |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskSaveReqVO.java
| @@ -33,7 +33,8 @@ public class MesWmStockTakingTaskSaveReqVO { | @@ -33,7 +33,8 @@ public class MesWmStockTakingTaskSaveReqVO { | ||
| 33 | @NotNull(message = "盘点人不能为空") | 33 | @NotNull(message = "盘点人不能为空") |
| 34 | private Long userId; | 34 | private Long userId; |
| 35 | 35 | ||
| 36 | - @Schema(description = "来源方案 ID", example = "1") | 36 | + @Schema(description = "来源方案 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 37 | + @NotNull(message = "来源方案不能为空") | ||
| 37 | private Long planId; | 38 | private Long planId; |
| 38 | 39 | ||
| 39 | @Schema(description = "开始时间") | 40 | @Schema(description = "开始时间") |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
| @@ -3,15 +3,15 @@ package cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock; | @@ -3,15 +3,15 @@ package cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO; | ||
| 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; | 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; |
| 7 | -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
| 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; | 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; |
| 9 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
| 9 | import org.apache.ibatis.annotations.Mapper; | 10 | import org.apache.ibatis.annotations.Mapper; |
| 10 | 11 | ||
| 11 | import java.math.BigDecimal; | 12 | import java.math.BigDecimal; |
| 12 | import java.util.Collection; | 13 | import java.util.Collection; |
| 13 | import java.util.List; | 14 | import java.util.List; |
| 14 | -import java.util.Set; | ||
| 15 | 15 | ||
| 16 | /** | 16 | /** |
| 17 | * MES 库存台账 Mapper | 17 | * MES 库存台账 Mapper |
| @@ -65,17 +65,17 @@ public interface MesWmMaterialStockMapper extends BaseMapperX<MesWmMaterialStock | @@ -65,17 +65,17 @@ public interface MesWmMaterialStockMapper extends BaseMapperX<MesWmMaterialStock | ||
| 65 | .eqIfPresent(MesWmMaterialStockDO::getBatchId, batchId)); | 65 | .eqIfPresent(MesWmMaterialStockDO::getBatchId, batchId)); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | - default List<MesWmMaterialStockDO> selectListForStockTaking(Set<Long> warehouseIds, Set<Long> locationIds, | ||
| 69 | - Set<Long> areaIds, Set<Long> itemIds, | ||
| 70 | - Set<Long> batchIds) { | 68 | + default List<MesWmMaterialStockDO> selectListForStockTaking(MesWmMaterialStockListReqVO reqVO) { |
| 71 | return selectList(new LambdaQueryWrapperX<MesWmMaterialStockDO>() | 69 | return selectList(new LambdaQueryWrapperX<MesWmMaterialStockDO>() |
| 72 | - .inIfPresent(MesWmMaterialStockDO::getWarehouseId, warehouseIds) | ||
| 73 | - .inIfPresent(MesWmMaterialStockDO::getLocationId, locationIds) | ||
| 74 | - .inIfPresent(MesWmMaterialStockDO::getAreaId, areaIds) | ||
| 75 | - .inIfPresent(MesWmMaterialStockDO::getItemId, itemIds) | ||
| 76 | - .inIfPresent(MesWmMaterialStockDO::getBatchId, batchIds) | ||
| 77 | - .ne(MesWmMaterialStockDO::getQuantityOnhand, BigDecimal.ZERO) | ||
| 78 | - .orderByAsc(MesWmMaterialStockDO::getId)); | 70 | + .eqIfPresent(MesWmMaterialStockDO::getWarehouseId, reqVO.getWarehouseId()) |
| 71 | + .eqIfPresent(MesWmMaterialStockDO::getLocationId, reqVO.getLocationId()) | ||
| 72 | + .eqIfPresent(MesWmMaterialStockDO::getAreaId, reqVO.getAreaId()) | ||
| 73 | + .eqIfPresent(MesWmMaterialStockDO::getItemId, reqVO.getItemId()) | ||
| 74 | + .eqIfPresent(MesWmMaterialStockDO::getBatchId, reqVO.getBatchId()) | ||
| 75 | + .geIfPresent(MesWmMaterialStockDO::getUpdateTime, reqVO.getStartTime()) | ||
| 76 | + .leIfPresent(MesWmMaterialStockDO::getUpdateTime, reqVO.getEndTime()) | ||
| 77 | + .ne(MesWmMaterialStockDO::getQuantityOnhand, BigDecimal.ZERO) // TODO @芋艿:需要在考虑下,要不要支持; | ||
| 78 | + .orderByAsc(MesWmMaterialStockDO::getRecptDate)); | ||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | } | 81 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| @@ -484,6 +484,7 @@ public interface ErrorCodeConstants { | @@ -484,6 +484,7 @@ public interface ErrorCodeConstants { | ||
| 484 | ErrorCode WM_STOCK_TAKING_TASK_NO_STOCK = new ErrorCode(1_040_714_115, "未找到符合条件的库存数据"); | 484 | ErrorCode WM_STOCK_TAKING_TASK_NO_STOCK = new ErrorCode(1_040_714_115, "未找到符合条件的库存数据"); |
| 485 | ErrorCode WM_STOCK_TAKING_TASK_NO_LINE = new ErrorCode(1_040_714_116, "盘点任务至少需要一条任务行"); | 485 | ErrorCode WM_STOCK_TAKING_TASK_NO_LINE = new ErrorCode(1_040_714_116, "盘点任务至少需要一条任务行"); |
| 486 | ErrorCode WM_STOCK_TAKING_TASK_LINE_NOT_EXISTS = new ErrorCode(1_040_714_117, "盘点任务行不存在"); | 486 | ErrorCode WM_STOCK_TAKING_TASK_LINE_NOT_EXISTS = new ErrorCode(1_040_714_117, "盘点任务行不存在"); |
| 487 | + ErrorCode WM_STOCK_TAKING_TASK_DYNAMIC_TIME_REQUIRED = new ErrorCode(1_040_714_118, "动态盘点必须选择开始时间和结束时间"); | ||
| 487 | 488 | ||
| 488 | // ========== MES 仓库管理-销售出库单(1-040-714-000) ========== | 489 | // ========== MES 仓库管理-销售出库单(1-040-714-000) ========== |
| 489 | ErrorCode WM_PRODUCT_SALES_NOT_EXISTS = new ErrorCode(1_040_714_000, "销售出库单不存在"); | 490 | ErrorCode WM_PRODUCT_SALES_NOT_EXISTS = new ErrorCode(1_040_714_000, "销售出库单不存在"); |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskLineStatusEnum.java
| @@ -6,7 +6,6 @@ import lombok.Getter; | @@ -6,7 +6,6 @@ import lombok.Getter; | ||
| 6 | 6 | ||
| 7 | import java.util.Arrays; | 7 | import java.util.Arrays; |
| 8 | 8 | ||
| 9 | -// TODO @AI:缺少注释;status + name 这种; | ||
| 10 | /** | 9 | /** |
| 11 | * MES 盘点任务行状态枚举 | 10 | * MES 盘点任务行状态枚举 |
| 12 | */ | 11 | */ |
| @@ -14,6 +13,7 @@ import java.util.Arrays; | @@ -14,6 +13,7 @@ import java.util.Arrays; | ||
| 14 | @AllArgsConstructor | 13 | @AllArgsConstructor |
| 15 | public enum MesWmStockTakingTaskLineStatusEnum implements ArrayValuable<Integer> { | 14 | public enum MesWmStockTakingTaskLineStatusEnum implements ArrayValuable<Integer> { |
| 16 | 15 | ||
| 16 | + // TODO @AI:UNCOUNTED 可以去掉! | ||
| 17 | UNCOUNTED(0, "未盘点"), | 17 | UNCOUNTED(0, "未盘点"), |
| 18 | NORMAL(1, "正常"), | 18 | NORMAL(1, "正常"), |
| 19 | GAIN(2, "盘盈"), | 19 | GAIN(2, "盘盈"), |
| @@ -22,7 +22,13 @@ public enum MesWmStockTakingTaskLineStatusEnum implements ArrayValuable<Integer> | @@ -22,7 +22,13 @@ public enum MesWmStockTakingTaskLineStatusEnum implements ArrayValuable<Integer> | ||
| 22 | public static final Integer[] ARRAYS = Arrays.stream(values()) | 22 | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| 23 | .map(MesWmStockTakingTaskLineStatusEnum::getStatus).toArray(Integer[]::new); | 23 | .map(MesWmStockTakingTaskLineStatusEnum::getStatus).toArray(Integer[]::new); |
| 24 | 24 | ||
| 25 | + /** | ||
| 26 | + * 状态 | ||
| 27 | + */ | ||
| 25 | private final Integer status; | 28 | private final Integer status; |
| 29 | + /** | ||
| 30 | + * 状态名称 | ||
| 31 | + */ | ||
| 26 | private final String name; | 32 | private final String name; |
| 27 | 33 | ||
| 28 | @Override | 34 | @Override |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java
| @@ -7,23 +7,50 @@ import lombok.Getter; | @@ -7,23 +7,50 @@ import lombok.Getter; | ||
| 7 | 7 | ||
| 8 | import java.util.Arrays; | 8 | import java.util.Arrays; |
| 9 | 9 | ||
| 10 | -// TODO @AI:缺少注释;status + name 这种; | ||
| 11 | /** | 10 | /** |
| 12 | * MES 盘点任务状态枚举 | 11 | * MES 盘点任务状态枚举 |
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 13 | */ | 14 | */ |
| 14 | @Getter | 15 | @Getter |
| 15 | @AllArgsConstructor | 16 | @AllArgsConstructor |
| 16 | public enum MesWmStockTakingTaskStatusEnum implements ArrayValuable<Integer> { | 17 | public enum MesWmStockTakingTaskStatusEnum implements ArrayValuable<Integer> { |
| 17 | 18 | ||
| 19 | + /** | ||
| 20 | + * 草稿 | ||
| 21 | + * | ||
| 22 | + * 对应方法:{@link cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskService#createStockTakingTask} | ||
| 23 | + */ | ||
| 18 | PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), | 24 | PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), |
| 25 | + /** | ||
| 26 | + * 审批中 | ||
| 27 | + * | ||
| 28 | + * 对应方法:{@link cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskService#submitStockTakingTask} | ||
| 29 | + */ | ||
| 19 | APPROVING(MesOrderStatusConstants.APPROVING, "审批中"), | 30 | APPROVING(MesOrderStatusConstants.APPROVING, "审批中"), |
| 31 | + /** | ||
| 32 | + * 已完成 | ||
| 33 | + * | ||
| 34 | + * 对应方法:{@link cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskService#finishStockTakingTask} | ||
| 35 | + */ | ||
| 20 | FINISHED(MesOrderStatusConstants.FINISHED, "已完成"), | 36 | FINISHED(MesOrderStatusConstants.FINISHED, "已完成"), |
| 37 | + /** | ||
| 38 | + * 已取消 | ||
| 39 | + * | ||
| 40 | + * 对应方法:{@link cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskService#cancelStockTakingTask} | ||
| 41 | + */ | ||
| 21 | CANCELED(MesOrderStatusConstants.CANCELLED, "已取消"); | 42 | CANCELED(MesOrderStatusConstants.CANCELLED, "已取消"); |
| 22 | 43 | ||
| 23 | public static final Integer[] ARRAYS = Arrays.stream(values()) | 44 | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| 24 | .map(MesWmStockTakingTaskStatusEnum::getStatus).toArray(Integer[]::new); | 45 | .map(MesWmStockTakingTaskStatusEnum::getStatus).toArray(Integer[]::new); |
| 25 | 46 | ||
| 47 | + /** | ||
| 48 | + * 状态 | ||
| 49 | + */ | ||
| 26 | private final Integer status; | 50 | private final Integer status; |
| 51 | + /** | ||
| 52 | + * 状态名称 | ||
| 53 | + */ | ||
| 27 | private final String name; | 54 | private final String name; |
| 28 | 55 | ||
| 29 | @Override | 56 | @Override |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java
| 1 | package cn.iocoder.yudao.module.mes.service.wm.materialstock; | 1 | package cn.iocoder.yudao.module.mes.service.wm.materialstock; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; | ||
| 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO; | 4 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO; |
| 5 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; | ||
| 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; | 7 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; |
| 7 | import jakarta.validation.Valid; | 8 | import jakarta.validation.Valid; |
| 8 | 9 | ||
| @@ -11,7 +12,6 @@ import java.time.LocalDateTime; | @@ -11,7 +12,6 @@ import java.time.LocalDateTime; | ||
| 11 | import java.util.Collection; | 12 | import java.util.Collection; |
| 12 | import java.util.List; | 13 | import java.util.List; |
| 13 | import java.util.Map; | 14 | import java.util.Map; |
| 14 | -import java.util.Set; | ||
| 15 | 15 | ||
| 16 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | 16 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| 17 | 17 | ||
| @@ -83,10 +83,13 @@ public interface MesWmMaterialStockService { | @@ -83,10 +83,13 @@ public interface MesWmMaterialStockService { | ||
| 83 | */ | 83 | */ |
| 84 | List<MesWmMaterialStockDO> getMaterialStockList(Collection<Long> ids); | 84 | List<MesWmMaterialStockDO> getMaterialStockList(Collection<Long> ids); |
| 85 | 85 | ||
| 86 | - // TODO @芋艿:不确定性;感觉就是一个查询接口,参数比较多; | ||
| 87 | - List<MesWmMaterialStockDO> getMaterialStockListForStockTaking(Set<Long> warehouseIds, Set<Long> locationIds, | ||
| 88 | - Set<Long> areaIds, Set<Long> itemIds, | ||
| 89 | - Set<Long> batchIds); | 86 | + /** |
| 87 | + * 获得物料库存列表(用于盘点等场景) | ||
| 88 | + * | ||
| 89 | + * @param reqVO 查询条件 | ||
| 90 | + * @return 物料库存列表 | ||
| 91 | + */ | ||
| 92 | + List<MesWmMaterialStockDO> getMaterialStockList(MesWmMaterialStockListReqVO reqVO); | ||
| 90 | 93 | ||
| 91 | default Map<Long, MesWmMaterialStockDO> getMaterialStockMap(Collection<Long> ids) { | 94 | default Map<Long, MesWmMaterialStockDO> getMaterialStockMap(Collection<Long> ids) { |
| 92 | return convertMap(getMaterialStockList(ids), MesWmMaterialStockDO::getId); | 95 | return convertMap(getMaterialStockList(ids), MesWmMaterialStockDO::getId); |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
| @@ -3,8 +3,9 @@ package cn.iocoder.yudao.module.mes.service.wm.materialstock; | @@ -3,8 +3,9 @@ package cn.iocoder.yudao.module.mes.service.wm.materialstock; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | 5 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; |
| 6 | -import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; | ||
| 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO; | 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO; |
| 7 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO; | ||
| 8 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; | ||
| 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; |
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; |
| @@ -108,10 +109,8 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService | @@ -108,10 +109,8 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService | ||
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | @Override | 111 | @Override |
| 111 | - public List<MesWmMaterialStockDO> getMaterialStockListForStockTaking(Set<Long> warehouseIds, Set<Long> locationIds, | ||
| 112 | - Set<Long> areaIds, Set<Long> itemIds, | ||
| 113 | - Set<Long> batchIds) { | ||
| 114 | - return materialStockMapper.selectListForStockTaking(warehouseIds, locationIds, areaIds, itemIds, batchIds); | 112 | + public List<MesWmMaterialStockDO> getMaterialStockList(MesWmMaterialStockListReqVO reqVO) { |
| 113 | + return materialStockMapper.selectListForStockTaking(reqVO); | ||
| 115 | } | 114 | } |
| 116 | 115 | ||
| 117 | // TODO DONE @AI:increaseStock 方法命名合理,语义清晰 | 116 | // TODO DONE @AI:increaseStock 方法命名合理,语义清晰 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/plan/MesWmStockTakingPlanService.java
| @@ -74,6 +74,14 @@ public interface MesWmStockTakingPlanService { | @@ -74,6 +74,14 @@ public interface MesWmStockTakingPlanService { | ||
| 74 | MesWmStockTakingPlanDO validateStockTakingPlanEditable(Long id); | 74 | MesWmStockTakingPlanDO validateStockTakingPlanEditable(Long id); |
| 75 | 75 | ||
| 76 | /** | 76 | /** |
| 77 | + * 校验盘点方案存在且已启用 | ||
| 78 | + * | ||
| 79 | + * @param id 盘点方案编号 | ||
| 80 | + * @return 盘点方案 | ||
| 81 | + */ | ||
| 82 | + MesWmStockTakingPlanDO validateStockTakingPlanEnabled(Long id); | ||
| 83 | + | ||
| 84 | + /** | ||
| 77 | * 获得盘点方案列表。 | 85 | * 获得盘点方案列表。 |
| 78 | * | 86 | * |
| 79 | * @param ids 盘点方案编号集合 | 87 | * @param ids 盘点方案编号集合 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/plan/MesWmStockTakingPlanServiceImpl.java
| @@ -135,6 +135,15 @@ public class MesWmStockTakingPlanServiceImpl implements MesWmStockTakingPlanServ | @@ -135,6 +135,15 @@ public class MesWmStockTakingPlanServiceImpl implements MesWmStockTakingPlanServ | ||
| 135 | } | 135 | } |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | + @Override | ||
| 139 | + public MesWmStockTakingPlanDO validateStockTakingPlanEnabled(Long id) { | ||
| 140 | + MesWmStockTakingPlanDO plan = validateStockTakingPlanExists(id); | ||
| 141 | + if (!CommonStatusEnum.isEnable(plan.getStatus())) { | ||
| 142 | + throw exception(WM_STOCK_TAKING_PLAN_NOT_ENABLED); | ||
| 143 | + } | ||
| 144 | + return plan; | ||
| 145 | + } | ||
| 146 | + | ||
| 138 | private MesWmStockTakingPlanDO validatePlanEditable(Long id) { | 147 | private MesWmStockTakingPlanDO validatePlanEditable(Long id) { |
| 139 | MesWmStockTakingPlanDO plan = validateStockTakingPlanExists(id); | 148 | MesWmStockTakingPlanDO plan = validateStockTakingPlanExists(id); |
| 140 | if (!CommonStatusEnum.isDisable(plan.getStatus())) { | 149 | if (!CommonStatusEnum.isDisable(plan.getStatus())) { |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskResultService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultPageReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO; | ||
| 6 | + | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * MES 盘点结果 Service 接口 | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +public interface MesWmStockTakingTaskResultService { | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * 分页查询盘点结果 | ||
| 18 | + * | ||
| 19 | + * @param pageReqVO 分页查询条件 | ||
| 20 | + * @return 盘点结果分页结果 | ||
| 21 | + */ | ||
| 22 | + PageResult<MesWmStockTakingTaskResultDO> getStockTakingTaskResultPage(MesWmStockTakingTaskResultPageReqVO pageReqVO); | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 获得盘点结果 | ||
| 26 | + * | ||
| 27 | + * @param id 盘点结果编号 | ||
| 28 | + * @return 盘点结果 | ||
| 29 | + */ | ||
| 30 | + MesWmStockTakingTaskResultDO getStockTakingTaskResult(Long id); | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * 获得盘点结果列表 | ||
| 34 | + * | ||
| 35 | + * @param taskId 盘点任务编号 | ||
| 36 | + * @return 盘点结果列表 | ||
| 37 | + */ | ||
| 38 | + List<MesWmStockTakingTaskResultDO> getStockTakingTaskResultList(Long taskId); | ||
| 39 | + | ||
| 40 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskResultServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultPageReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO; | ||
| 6 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskResultMapper; | ||
| 7 | +import jakarta.annotation.Resource; | ||
| 8 | +import org.springframework.stereotype.Service; | ||
| 9 | +import org.springframework.validation.annotation.Validated; | ||
| 10 | + | ||
| 11 | +import java.util.List; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * MES 盘点结果 Service 实现类 | ||
| 15 | + * | ||
| 16 | + * @author 芋道源码 | ||
| 17 | + */ | ||
| 18 | +@Service | ||
| 19 | +@Validated | ||
| 20 | +public class MesWmStockTakingTaskResultServiceImpl implements MesWmStockTakingTaskResultService { | ||
| 21 | + | ||
| 22 | + @Resource | ||
| 23 | + private MesWmStockTakingTaskResultMapper stockTakingTaskResultMapper; | ||
| 24 | + | ||
| 25 | + @Override | ||
| 26 | + public PageResult<MesWmStockTakingTaskResultDO> getStockTakingTaskResultPage( | ||
| 27 | + MesWmStockTakingTaskResultPageReqVO pageReqVO) { | ||
| 28 | + return stockTakingTaskResultMapper.selectPage(pageReqVO); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + @Override | ||
| 32 | + public MesWmStockTakingTaskResultDO getStockTakingTaskResult(Long id) { | ||
| 33 | + return stockTakingTaskResultMapper.selectById(id); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + @Override | ||
| 37 | + public List<MesWmStockTakingTaskResultDO> getStockTakingTaskResultList(Long taskId) { | ||
| 38 | + return stockTakingTaskResultMapper.selectListByTaskId(taskId); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLineBatchUpdateReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWmStockTakingTaskPageReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWmStockTakingTaskSaveReqVO; | ||
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO; | ||
| 8 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO; | ||
| 9 | +import jakarta.validation.Valid; | ||
| 10 | + | ||
| 11 | +import java.util.Collection; | ||
| 12 | +import java.util.List; | ||
| 13 | +import java.util.Map; | ||
| 14 | + | ||
| 15 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * MES 盘点任务 Service 接口 | ||
| 19 | + * | ||
| 20 | + * @author 芋道源码 | ||
| 21 | + */ | ||
| 22 | +public interface MesWmStockTakingTaskService { | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 创建盘点任务 | ||
| 26 | + * | ||
| 27 | + * @param createReqVO 创建信息 | ||
| 28 | + * @return 盘点任务编号 | ||
| 29 | + */ | ||
| 30 | + Long createStockTakingTask(@Valid MesWmStockTakingTaskSaveReqVO createReqVO); | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * 更新盘点任务 | ||
| 34 | + * | ||
| 35 | + * @param updateReqVO 更新信息 | ||
| 36 | + */ | ||
| 37 | + void updateStockTakingTask(@Valid MesWmStockTakingTaskSaveReqVO updateReqVO); | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * 删除盘点任务 | ||
| 41 | + * | ||
| 42 | + * @param id 盘点任务编号 | ||
| 43 | + */ | ||
| 44 | + void deleteStockTakingTask(Long id); | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 提交盘点任务 | ||
| 48 | + * | ||
| 49 | + * @param id 盘点任务编号 | ||
| 50 | + */ | ||
| 51 | + void submitStockTakingTask(Long id); | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * 完成盘点任务 | ||
| 55 | + * | ||
| 56 | + * @param id 盘点任务编号 | ||
| 57 | + */ | ||
| 58 | + void finishStockTakingTask(Long id); | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 取消盘点任务 | ||
| 62 | + * | ||
| 63 | + * @param id 盘点任务编号 | ||
| 64 | + */ | ||
| 65 | + void cancelStockTakingTask(Long id); | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * 批量更新盘点任务行 | ||
| 69 | + * | ||
| 70 | + * @param updateReqVO 更新信息 | ||
| 71 | + */ | ||
| 72 | + void updateStockTakingTaskLines(@Valid MesWmStockTakingTaskLineBatchUpdateReqVO updateReqVO); | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * 获得盘点任务 | ||
| 76 | + * | ||
| 77 | + * @param id 盘点任务编号 | ||
| 78 | + * @return 盘点任务 | ||
| 79 | + */ | ||
| 80 | + MesWmStockTakingTaskDO getStockTakingTask(Long id); | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * 校验盘点任务是否存在 | ||
| 84 | + * | ||
| 85 | + * @param id 盘点任务编号 | ||
| 86 | + * @return 盘点任务 | ||
| 87 | + */ | ||
| 88 | + MesWmStockTakingTaskDO validateStockTakingTaskExists(Long id); | ||
| 89 | + | ||
| 90 | + /** | ||
| 91 | + * 获得盘点任务列表 | ||
| 92 | + * | ||
| 93 | + * @param ids 盘点任务编号集合 | ||
| 94 | + * @return 盘点任务列表 | ||
| 95 | + */ | ||
| 96 | + List<MesWmStockTakingTaskDO> getStockTakingTaskList(Collection<Long> ids); | ||
| 97 | + | ||
| 98 | + /** | ||
| 99 | + * 获得盘点任务 Map | ||
| 100 | + * | ||
| 101 | + * @param ids 盘点任务编号集合 | ||
| 102 | + * @return 盘点任务 Map | ||
| 103 | + */ | ||
| 104 | + default Map<Long, MesWmStockTakingTaskDO> getStockTakingTaskMap(Collection<Long> ids) { | ||
| 105 | + return convertMap(getStockTakingTaskList(ids), MesWmStockTakingTaskDO::getId); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + /** | ||
| 109 | + * 分页查询盘点任务 | ||
| 110 | + * | ||
| 111 | + * @param pageReqVO 分页查询条件 | ||
| 112 | + * @return 盘点任务分页结果 | ||
| 113 | + */ | ||
| 114 | + PageResult<MesWmStockTakingTaskDO> getStockTakingTaskPage(MesWmStockTakingTaskPageReqVO pageReqVO); | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * 获得盘点任务行列表 | ||
| 118 | + * | ||
| 119 | + * @param taskId 盘点任务编号 | ||
| 120 | + * @return 盘点任务行列表 | ||
| 121 | + */ | ||
| 122 | + List<MesWmStockTakingTaskLineDO> getStockTakingTaskLineList(Long taskId); | ||
| 123 | + | ||
| 124 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.hutool.core.lang.Assert; | ||
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 6 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 7 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO; | ||
| 8 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO; | ||
| 9 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWmStockTakingTaskPageReqVO; | ||
| 10 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWmStockTakingTaskSaveReqVO; | ||
| 11 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLineBatchUpdateReqVO; | ||
| 12 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; | ||
| 13 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.plan.MesWmStockTakingPlanParamDO; | ||
| 14 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO; | ||
| 15 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO; | ||
| 16 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO; | ||
| 17 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.plan.MesWmStockTakingPlanMapper; | ||
| 18 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.plan.MesWmStockTakingPlanParamMapper; | ||
| 19 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskLineMapper; | ||
| 20 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskMapper; | ||
| 21 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskResultMapper; | ||
| 22 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingPlanParamTypeEnum; | ||
| 23 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingTaskLineStatusEnum; | ||
| 24 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingTaskStatusEnum; | ||
| 25 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingTypeEnum; | ||
| 26 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | ||
| 27 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||
| 28 | +import jakarta.annotation.Resource; | ||
| 29 | +import org.springframework.stereotype.Service; | ||
| 30 | +import org.springframework.transaction.annotation.Transactional; | ||
| 31 | +import org.springframework.validation.annotation.Validated; | ||
| 32 | + | ||
| 33 | +import java.math.BigDecimal; | ||
| 34 | +import java.time.LocalDateTime; | ||
| 35 | +import java.util.*; | ||
| 36 | +import java.util.stream.Collectors; | ||
| 37 | + | ||
| 38 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 39 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 40 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; | ||
| 41 | + | ||
| 42 | +/** | ||
| 43 | + * MES 盘点任务 Service 实现类 | ||
| 44 | + * | ||
| 45 | + * @author 芋道源码 | ||
| 46 | + */ | ||
| 47 | +@Service | ||
| 48 | +@Validated | ||
| 49 | +public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskService { | ||
| 50 | + | ||
| 51 | + @Resource | ||
| 52 | + private MesWmStockTakingTaskMapper stockTakingTaskMapper; | ||
| 53 | + @Resource | ||
| 54 | + private MesWmStockTakingTaskLineMapper stockTakingTaskLineMapper; | ||
| 55 | + @Resource | ||
| 56 | + private MesWmStockTakingTaskResultMapper stockTakingTaskResultMapper; | ||
| 57 | + @Resource | ||
| 58 | + private MesWmStockTakingPlanParamMapper stockTakingPlanParamMapper; | ||
| 59 | + @Resource | ||
| 60 | + private MesWmStockTakingPlanMapper stockTakingPlanMapper; | ||
| 61 | + @Resource | ||
| 62 | + private MesWmMaterialStockService materialStockService; | ||
| 63 | + @Resource | ||
| 64 | + private AdminUserApi adminUserApi; | ||
| 65 | + @Resource | ||
| 66 | + private cn.iocoder.yudao.module.mes.service.wm.stocktaking.plan.MesWmStockTakingPlanService stockTakingPlanService; | ||
| 67 | + | ||
| 68 | + @Override | ||
| 69 | + @Transactional(rollbackFor = Exception.class) | ||
| 70 | + public Long createStockTakingTask(MesWmStockTakingTaskSaveReqVO createReqVO) { | ||
| 71 | + // 1.1 校验 code 唯一 | ||
| 72 | + validateTaskCodeUnique(null, createReqVO.getCode()); | ||
| 73 | + // 1.2 校验方案存在 | ||
| 74 | + adminUserApi.validateUser(createReqVO.getUserId()); | ||
| 75 | + // 1.3 校验方案可用 | ||
| 76 | + stockTakingPlanService.validateStockTakingPlanEnabled(createReqVO.getPlanId()); | ||
| 77 | + | ||
| 78 | + // 2. 插入任务 | ||
| 79 | + MesWmStockTakingTaskDO task = BeanUtils.toBean(createReqVO, MesWmStockTakingTaskDO.class) | ||
| 80 | + .setStatus(MesWmStockTakingTaskStatusEnum.PREPARE.getStatus()); | ||
| 81 | + stockTakingTaskMapper.insert(task); | ||
| 82 | + | ||
| 83 | + // 3. 根据方案生成盘点明细行 | ||
| 84 | + generateStockTakingLines(task); | ||
| 85 | + return task.getId(); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + @Override | ||
| 89 | + @Transactional(rollbackFor = Exception.class) | ||
| 90 | + public void updateStockTakingTask(MesWmStockTakingTaskSaveReqVO updateReqVO) { | ||
| 91 | + // 1.1 校验任务存在且为草稿状态 | ||
| 92 | + validateTaskExistsAndPrepare(updateReqVO.getId()); | ||
| 93 | + // 1.2 校验 code 唯一 | ||
| 94 | + validateTaskCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); | ||
| 95 | + // 1.3 校验方案存在 | ||
| 96 | + adminUserApi.validateUser(updateReqVO.getUserId()); | ||
| 97 | + // 1.4 校验方案可用 | ||
| 98 | + stockTakingPlanService.validateStockTakingPlanEnabled(updateReqVO.getPlanId()); | ||
| 99 | + | ||
| 100 | + // 2. 更新任务 | ||
| 101 | + MesWmStockTakingTaskDO updateObj = BeanUtils.toBean(updateReqVO, MesWmStockTakingTaskDO.class); | ||
| 102 | + stockTakingTaskMapper.updateById(updateObj); | ||
| 103 | + | ||
| 104 | + // 3. 删除老的明细,重新生成新的 | ||
| 105 | + stockTakingTaskLineMapper.deleteByTaskId(updateReqVO.getId()); | ||
| 106 | + generateStockTakingLines(updateObj); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + @Override | ||
| 110 | + @Transactional(rollbackFor = Exception.class) | ||
| 111 | + public void deleteStockTakingTask(Long id) { | ||
| 112 | + // 1. 校验任务存在且为草稿状态 | ||
| 113 | + validateTaskExistsAndPrepare(id); | ||
| 114 | + | ||
| 115 | + // 2. 删除任务和明细 | ||
| 116 | + stockTakingTaskResultMapper.deleteByTaskId(id); | ||
| 117 | + stockTakingTaskLineMapper.deleteByTaskId(id); | ||
| 118 | + stockTakingTaskMapper.deleteById(id); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + @Override | ||
| 122 | + @Transactional(rollbackFor = Exception.class) | ||
| 123 | + public void submitStockTakingTask(Long id) { | ||
| 124 | + // 1.1 校验任务存在且为草稿状态 | ||
| 125 | + MesWmStockTakingTaskDO task = validateTaskExistsAndPrepare(id); | ||
| 126 | + // 1.2 检查要盘点的内容 | ||
| 127 | + List<MesWmStockTakingTaskLineDO> lines = stockTakingTaskLineMapper.selectListByTaskId(id); | ||
| 128 | + if (CollUtil.isEmpty(lines)) { | ||
| 129 | + throw exception(WM_STOCK_TAKING_TASK_NO_LINE); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + // 2. 更新任务状态为审批中 | ||
| 133 | + stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO().setId(id) | ||
| 134 | + .setStatus(MesWmStockTakingTaskStatusEnum.APPROVING.getStatus())); | ||
| 135 | + | ||
| 136 | + // 3. 根据冻结标识,对物资进行冻结 | ||
| 137 | + // TODO @芋艿:后续跟进下! | ||
| 138 | + if (Boolean.TRUE.equals(task.getFrozenFlag())) { | ||
| 139 | + for (MesWmStockTakingTaskLineDO line : lines) { | ||
| 140 | + if (line.getMaterialStockId() != null) { | ||
| 141 | + updateFrozen(line.getMaterialStockId(), true); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + /** | ||
| 148 | + * 根据盘点方案生成盘点明细行 | ||
| 149 | + * | ||
| 150 | + * @param task 盘点任务 | ||
| 151 | + */ | ||
| 152 | + private void generateStockTakingLines(MesWmStockTakingTaskDO task) { | ||
| 153 | + // 1.1 构建查询条件(包含动态盘点时间校验) | ||
| 154 | + MesWmMaterialStockListReqVO reqVO = buildStockQueryReqVO(task); | ||
| 155 | + // 1.2 查询物料库存 | ||
| 156 | + List<MesWmMaterialStockDO> stocks = materialStockService.getMaterialStockList(reqVO); | ||
| 157 | + if (CollUtil.isEmpty(stocks)) { | ||
| 158 | + throw exception(WM_STOCK_TAKING_TASK_NO_STOCK); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + // 2. 批量生成明细行 | ||
| 162 | + // TODO DONE @AI:把 stocks 作为参数,传递给 stocktakingTaskLineService,更收敛;(当前直接插入更简洁) | ||
| 163 | + List<MesWmStockTakingTaskLineDO> lines = new ArrayList<>(stocks.size()); | ||
| 164 | + for (MesWmMaterialStockDO stock : stocks) { | ||
| 165 | + MesWmStockTakingTaskLineDO line = MesWmStockTakingTaskLineDO.builder() | ||
| 166 | + .taskId(task.getId()) | ||
| 167 | + .materialStockId(stock.getId()) | ||
| 168 | + .itemId(stock.getItemId()) | ||
| 169 | + .batchId(stock.getBatchId()) | ||
| 170 | + .quantity(defaultQuantity(stock.getQuantityOnhand())) | ||
| 171 | + .warehouseId(stock.getWarehouseId()) | ||
| 172 | + .locationId(stock.getLocationId()) | ||
| 173 | + .areaId(stock.getAreaId()) | ||
| 174 | + .status(MesWmStockTakingTaskLineStatusEnum.LOSS.getStatus()) | ||
| 175 | + .build(); | ||
| 176 | + lines.add(line); | ||
| 177 | + } | ||
| 178 | + stockTakingTaskLineMapper.insertBatch(lines); | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + /** | ||
| 182 | + * 构建库存查询条件 | ||
| 183 | + * | ||
| 184 | + * @param task 盘点任务 | ||
| 185 | + * @return 查询条件 VO | ||
| 186 | + */ | ||
| 187 | + private MesWmMaterialStockListReqVO buildStockQueryReqVO(MesWmStockTakingTaskDO task) { | ||
| 188 | + // 1. 从方案参数中提取过滤条件 | ||
| 189 | + List<MesWmStockTakingPlanParamDO> params = stockTakingPlanParamMapper.selectListByPlanId(task.getPlanId()); | ||
| 190 | + Assert.notEmpty(params, "盘点方案参数不能为空"); | ||
| 191 | + | ||
| 192 | + // 2.1 拼接通用参数 | ||
| 193 | + MesWmMaterialStockListReqVO reqVO = new MesWmMaterialStockListReqVO() | ||
| 194 | + .setWarehouseId(extractMesWmStockTakingPlanParamValueId(params, MesWmStockTakingPlanParamTypeEnum.WAREHOUSE.getType())) | ||
| 195 | + .setLocationId(extractMesWmStockTakingPlanParamValueId(params, MesWmStockTakingPlanParamTypeEnum.LOCATION.getType())) | ||
| 196 | + .setAreaId(extractMesWmStockTakingPlanParamValueId(params, MesWmStockTakingPlanParamTypeEnum.AREA.getType())) | ||
| 197 | + .setItemId(extractMesWmStockTakingPlanParamValueId(params, MesWmStockTakingPlanParamTypeEnum.ITEM.getType())) | ||
| 198 | + .setBatchId(extractMesWmStockTakingPlanParamValueId(params, MesWmStockTakingPlanParamTypeEnum.BATCH.getType())); | ||
| 199 | + // 2.2 对于动态盘点,设置时间参数并校验 | ||
| 200 | + if (MesWmStockTakingTypeEnum.DYNAMIC.getType().equals(task.getType())) { | ||
| 201 | + Assert.notNull(task.getStartTime(), "动态盘点开始时间不能为空"); | ||
| 202 | + Assert.notNull(task.getEndTime(), "动态盘点结束时间不能为空"); | ||
| 203 | + reqVO.setStartTime(task.getStartTime()).setEndTime(task.getEndTime()); | ||
| 204 | + } | ||
| 205 | + return reqVO; | ||
| 206 | + } | ||
| 207 | + | ||
| 208 | + /** | ||
| 209 | + * 从参数列表中提取第一个匹配类型的参数 ID | ||
| 210 | + * | ||
| 211 | + * @param params 参数列表 | ||
| 212 | + * @param type 参数类型 | ||
| 213 | + * @return 参数 ID(如果有多个,取第一个) | ||
| 214 | + */ | ||
| 215 | + private Long extractMesWmStockTakingPlanParamValueId(List<MesWmStockTakingPlanParamDO> params, Integer type) { | ||
| 216 | + MesWmStockTakingPlanParamDO param = CollUtil.findOne(params, | ||
| 217 | + item -> Objects.equals(item.getType(), type) && item.getValueId() != null); | ||
| 218 | + return param != null ? param.getValueId() : null; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + @Override | ||
| 222 | + @Transactional(rollbackFor = Exception.class) | ||
| 223 | + public void finishStockTakingTask(Long id) { | ||
| 224 | + // TODO @AI:补全下注释; | ||
| 225 | + // TODO @AI:notEquals; | ||
| 226 | + MesWmStockTakingTaskDO task = validateTaskExists(id); | ||
| 227 | + if (!MesWmStockTakingTaskStatusEnum.APPROVING.getStatus().equals(task.getStatus())) { | ||
| 228 | + throw exception(WM_STOCK_TAKING_TASK_NOT_APPROVING); | ||
| 229 | + } | ||
| 230 | + List<MesWmStockTakingTaskLineDO> lines = stockTakingTaskLineMapper.selectListByTaskId(id); | ||
| 231 | + if (CollUtil.isEmpty(lines)) { | ||
| 232 | + throw exception(WM_STOCK_TAKING_TASK_NO_LINE); | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + stockTakingTaskResultMapper.deleteByTaskId(id); | ||
| 236 | + for (MesWmStockTakingTaskLineDO line : lines) { | ||
| 237 | + if (MesWmStockTakingTaskLineStatusEnum.NORMAL.getStatus().equals(line.getStatus()) | ||
| 238 | + || MesWmStockTakingTaskLineStatusEnum.UNCOUNTED.getStatus().equals(line.getStatus())) { | ||
| 239 | + continue; | ||
| 240 | + } | ||
| 241 | + stockTakingTaskResultMapper.insert(MesWmStockTakingTaskResultDO.builder() | ||
| 242 | + .taskId(id) | ||
| 243 | + .lineId(line.getId()) | ||
| 244 | + .materialStockId(line.getMaterialStockId()) | ||
| 245 | + .itemId(line.getItemId()) | ||
| 246 | + .batchId(line.getBatchId()) | ||
| 247 | + .batchCode(line.getBatchCode()) | ||
| 248 | + .warehouseId(line.getWarehouseId()) | ||
| 249 | + .locationId(line.getLocationId()) | ||
| 250 | + .areaId(line.getAreaId()) | ||
| 251 | + .quantity(differenceQuantity(line)) | ||
| 252 | + .remark(line.getRemark()) | ||
| 253 | + .build()); | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + task.setEndTime(LocalDateTime.now()); | ||
| 257 | + task.setStatus(MesWmStockTakingTaskStatusEnum.FINISHED.getStatus()); | ||
| 258 | + stockTakingTaskMapper.updateById(task); | ||
| 259 | + if (Boolean.TRUE.equals(task.getFrozenFlag())) { | ||
| 260 | + unfreezeTaskStocks(lines); | ||
| 261 | + } | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + @Override | ||
| 265 | + @Transactional(rollbackFor = Exception.class) | ||
| 266 | + public void cancelStockTakingTask(Long id) { | ||
| 267 | + MesWmStockTakingTaskDO task = validateTaskExists(id); | ||
| 268 | + if (MesWmStockTakingTaskStatusEnum.FINISHED.getStatus().equals(task.getStatus()) | ||
| 269 | + || MesWmStockTakingTaskStatusEnum.CANCELED.getStatus().equals(task.getStatus())) { | ||
| 270 | + throw exception(WM_STOCK_TAKING_TASK_CANNOT_CANCEL); | ||
| 271 | + } | ||
| 272 | + task.setStatus(MesWmStockTakingTaskStatusEnum.CANCELED.getStatus()); | ||
| 273 | + stockTakingTaskMapper.updateById(task); | ||
| 274 | + if (Boolean.TRUE.equals(task.getFrozenFlag())) { | ||
| 275 | + unfreezeTaskStocks(stockTakingTaskLineMapper.selectListByTaskId(id)); | ||
| 276 | + } | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + @Override | ||
| 280 | + @Transactional(rollbackFor = Exception.class) | ||
| 281 | + public void updateStockTakingTaskLines(MesWmStockTakingTaskLineBatchUpdateReqVO updateReqVO) { | ||
| 282 | + MesWmStockTakingTaskDO task = validateTaskExists(updateReqVO.getTaskId()); | ||
| 283 | + if (!MesWmStockTakingTaskStatusEnum.APPROVING.getStatus().equals(task.getStatus())) { | ||
| 284 | + throw exception(WM_STOCK_TAKING_TASK_NOT_APPROVING); | ||
| 285 | + } | ||
| 286 | + | ||
| 287 | + Set<Long> lineIds = convertSet(updateReqVO.getItems(), MesWmStockTakingTaskLineBatchUpdateReqVO.Item::getId); | ||
| 288 | + List<MesWmStockTakingTaskLineDO> lines = stockTakingTaskLineMapper.selectListByTaskIdAndIds(updateReqVO.getTaskId(), lineIds); | ||
| 289 | + if (lines.size() != updateReqVO.getItems().size()) { | ||
| 290 | + throw exception(WM_STOCK_TAKING_TASK_LINE_NOT_EXISTS); | ||
| 291 | + } | ||
| 292 | + Map<Long, MesWmStockTakingTaskLineDO> lineMap = lines.stream() | ||
| 293 | + .collect(Collectors.toMap(MesWmStockTakingTaskLineDO::getId, item -> item)); | ||
| 294 | + for (MesWmStockTakingTaskLineBatchUpdateReqVO.Item item : updateReqVO.getItems()) { | ||
| 295 | + MesWmStockTakingTaskLineDO line = lineMap.get(item.getId()); | ||
| 296 | + line.setTakingQuantity(item.getTakingQuantity()); | ||
| 297 | + line.setRemark(item.getRemark()); | ||
| 298 | + line.setStatus(resolveLineStatus(line.getQuantity(), item.getTakingQuantity())); | ||
| 299 | + stockTakingTaskLineMapper.updateById(line); | ||
| 300 | + } | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + @Override | ||
| 304 | + public MesWmStockTakingTaskDO getStockTakingTask(Long id) { | ||
| 305 | + return stockTakingTaskMapper.selectById(id); | ||
| 306 | + } | ||
| 307 | + | ||
| 308 | + @Override | ||
| 309 | + public MesWmStockTakingTaskDO validateStockTakingTaskExists(Long id) { | ||
| 310 | + return validateTaskExists(id); | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + @Override | ||
| 314 | + public List<MesWmStockTakingTaskDO> getStockTakingTaskList(Collection<Long> ids) { | ||
| 315 | + if (CollUtil.isEmpty(ids)) { | ||
| 316 | + return Collections.emptyList(); | ||
| 317 | + } | ||
| 318 | + return stockTakingTaskMapper.selectByIds(ids); | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + @Override | ||
| 322 | + public PageResult<MesWmStockTakingTaskDO> getStockTakingTaskPage(MesWmStockTakingTaskPageReqVO pageReqVO) { | ||
| 323 | + return stockTakingTaskMapper.selectPage(pageReqVO); | ||
| 324 | + } | ||
| 325 | + | ||
| 326 | + @Override | ||
| 327 | + public List<MesWmStockTakingTaskLineDO> getStockTakingTaskLineList(Long taskId) { | ||
| 328 | + return stockTakingTaskLineMapper.selectListByTaskId(taskId); | ||
| 329 | + } | ||
| 330 | + | ||
| 331 | + private void updateFrozen(Long materialStockId, boolean frozen) { | ||
| 332 | + MesWmMaterialStockFreezeReqVO reqVO = new MesWmMaterialStockFreezeReqVO(); | ||
| 333 | + reqVO.setId(materialStockId); | ||
| 334 | + reqVO.setFrozen(frozen); | ||
| 335 | + materialStockService.updateMaterialStockFrozen(reqVO); | ||
| 336 | + } | ||
| 337 | + | ||
| 338 | + private void unfreezeTaskStocks(List<MesWmStockTakingTaskLineDO> lines) { | ||
| 339 | + if (CollUtil.isEmpty(lines)) { | ||
| 340 | + return; | ||
| 341 | + } | ||
| 342 | + for (MesWmStockTakingTaskLineDO line : lines) { | ||
| 343 | + if (line.getMaterialStockId() != null) { | ||
| 344 | + updateFrozen(line.getMaterialStockId(), false); | ||
| 345 | + } | ||
| 346 | + } | ||
| 347 | + } | ||
| 348 | + | ||
| 349 | + private Integer resolveLineStatus(BigDecimal quantity, BigDecimal takingQuantity) { | ||
| 350 | + if (takingQuantity == null) { | ||
| 351 | + return MesWmStockTakingTaskLineStatusEnum.UNCOUNTED.getStatus(); | ||
| 352 | + } | ||
| 353 | + int compare = takingQuantity.compareTo(defaultQuantity(quantity)); | ||
| 354 | + if (compare == 0) { | ||
| 355 | + return MesWmStockTakingTaskLineStatusEnum.NORMAL.getStatus(); | ||
| 356 | + } | ||
| 357 | + return compare > 0 ? MesWmStockTakingTaskLineStatusEnum.GAIN.getStatus() | ||
| 358 | + : MesWmStockTakingTaskLineStatusEnum.LOSS.getStatus(); | ||
| 359 | + } | ||
| 360 | + | ||
| 361 | + private BigDecimal differenceQuantity(MesWmStockTakingTaskLineDO line) { | ||
| 362 | + return defaultQuantity(line.getTakingQuantity()).subtract(defaultQuantity(line.getQuantity())); | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | + private BigDecimal defaultQuantity(BigDecimal quantity) { | ||
| 366 | + return quantity == null ? BigDecimal.ZERO : quantity; | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + private void validateTaskCodeUnique(Long id, String code) { | ||
| 370 | + MesWmStockTakingTaskDO task = stockTakingTaskMapper.selectByCode(code); | ||
| 371 | + if (task == null) { | ||
| 372 | + return; | ||
| 373 | + } | ||
| 374 | + if (id == null || !Objects.equals(task.getId(), id)) { | ||
| 375 | + throw exception(WM_STOCK_TAKING_TASK_CODE_DUPLICATE); | ||
| 376 | + } | ||
| 377 | + } | ||
| 378 | + | ||
| 379 | + private void validatePlanExists(Long id) { | ||
| 380 | + if (stockTakingPlanMapper.selectById(id) == null) { | ||
| 381 | + throw exception(WM_STOCK_TAKING_PLAN_NOT_EXISTS); | ||
| 382 | + } | ||
| 383 | + } | ||
| 384 | + | ||
| 385 | + private MesWmStockTakingTaskDO validateTaskExists(Long id) { | ||
| 386 | + MesWmStockTakingTaskDO task = stockTakingTaskMapper.selectById(id); | ||
| 387 | + if (task == null) { | ||
| 388 | + throw exception(WM_STOCK_TAKING_TASK_NOT_EXISTS); | ||
| 389 | + } | ||
| 390 | + return task; | ||
| 391 | + } | ||
| 392 | + | ||
| 393 | + private MesWmStockTakingTaskDO validateTaskExistsAndPrepare(Long id) { | ||
| 394 | + MesWmStockTakingTaskDO task = validateTaskExists(id); | ||
| 395 | + if (!MesWmStockTakingTaskStatusEnum.PREPARE.getStatus().equals(task.getStatus())) { | ||
| 396 | + throw exception(WM_STOCK_TAKING_TASK_NOT_PREPARE); | ||
| 397 | + } | ||
| 398 | + return task; | ||
| 399 | + } | ||
| 400 | + | ||
| 401 | +} |