Commit dfa61b7d7e9d8dbb3c2bc3aa68d31d1ff29b0c24
1 parent
92a5a2bd
✨ feat(wm): 添加物料消耗记录及相关服务实现
Showing
15 changed files
with
449 additions
and
40 deletions
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/config/ConfigApi.java
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/api/websocket/WebSocketSenderApi.java
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java
| ... | ... | @@ -48,6 +48,7 @@ import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPOR |
| 48 | 48 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 49 | 49 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 50 | 50 | import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; |
| 51 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 51 | 52 | |
| 52 | 53 | @Tag(name = "管理后台 - MES 生产报工") |
| 53 | 54 | @RestController |
| ... | ... | @@ -156,7 +157,7 @@ public class MesProFeedbackController { |
| 156 | 157 | @Parameter(name = "id", description = "编号", required = true) |
| 157 | 158 | @PreAuthorize("@ss.hasPermission('mes:pro-feedback:approve')") |
| 158 | 159 | public CommonResult<Boolean> approveFeedback(@RequestParam("id") Long id) { |
| 159 | - return success(feedbackService.approveFeedback(id)); | |
| 160 | + return success(feedbackService.approveFeedback(id, getLoginUserId())); | |
| 160 | 161 | } |
| 161 | 162 | |
| 162 | 163 | // ==================== 拼接 VO ==================== | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; | |
| 5 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | |
| 6 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO; | |
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; | |
| 8 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; | |
| 9 | +import com.baomidou.mybatisplus.annotation.KeySequence; | |
| 10 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 11 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 12 | +import lombok.*; | |
| 13 | + | |
| 14 | +import java.time.LocalDateTime; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * MES 物料消耗记录 DO | |
| 18 | + * | |
| 19 | + * @author 芋道源码 | |
| 20 | + */ | |
| 21 | +@TableName("mes_wm_item_consume") | |
| 22 | +@KeySequence("mes_wm_item_consume_seq") | |
| 23 | +@Data | |
| 24 | +@EqualsAndHashCode(callSuper = true) | |
| 25 | +@ToString(callSuper = true) | |
| 26 | +@Builder | |
| 27 | +@NoArgsConstructor | |
| 28 | +@AllArgsConstructor | |
| 29 | +public class MesWmItemConsumeDO extends BaseDO { | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 编号 | |
| 33 | + */ | |
| 34 | + @TableId | |
| 35 | + private Long id; | |
| 36 | + /** | |
| 37 | + * 生产工单编号 | |
| 38 | + * | |
| 39 | + * 关联 {@link MesProWorkOrderDO#getId()} | |
| 40 | + */ | |
| 41 | + private Long workOrderId; | |
| 42 | + /** | |
| 43 | + * 生产任务编号 | |
| 44 | + * | |
| 45 | + * 关联 {@link MesProTaskDO#getId()} | |
| 46 | + */ | |
| 47 | + private Long taskId; | |
| 48 | + /** | |
| 49 | + * 工作站编号 | |
| 50 | + * | |
| 51 | + * 关联 {@link MesMdWorkstationDO#getId()} | |
| 52 | + */ | |
| 53 | + private Long workstationId; | |
| 54 | + /** | |
| 55 | + * 工序编号 | |
| 56 | + * | |
| 57 | + * 关联 {@link MesProProcessDO#getId()} | |
| 58 | + */ | |
| 59 | + private Long processId; | |
| 60 | + /** | |
| 61 | + * 报工记录编号 | |
| 62 | + * | |
| 63 | + * 关联 {@link MesProFeedbackDO#getId()} | |
| 64 | + */ | |
| 65 | + private Long feedbackId; | |
| 66 | + /** | |
| 67 | + * 消耗日期 | |
| 68 | + */ | |
| 69 | + private LocalDateTime consumeDate; | |
| 70 | + // DONE @AI:搞个独立的枚举类; | |
| 71 | + /** | |
| 72 | + * 状态 | |
| 73 | + * | |
| 74 | + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.wm.MesWmItemConsumeStatusEnum} | |
| 75 | + */ | |
| 76 | + private Integer status; | |
| 77 | + /** | |
| 78 | + * 备注 | |
| 79 | + */ | |
| 80 | + private String remark; | |
| 81 | + | |
| 82 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemconsume/MesWmItemConsumeLineDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; | |
| 5 | +import com.baomidou.mybatisplus.annotation.KeySequence; | |
| 6 | +import com.baomidou.mybatisplus.annotation.TableId; | |
| 7 | +import com.baomidou.mybatisplus.annotation.TableName; | |
| 8 | +import lombok.*; | |
| 9 | + | |
| 10 | +import java.math.BigDecimal; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * MES 物料消耗记录行 DO | |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +@TableName("mes_wm_item_consume_line") | |
| 18 | +@KeySequence("mes_wm_item_consume_line_seq") | |
| 19 | +@Data | |
| 20 | +@EqualsAndHashCode(callSuper = true) | |
| 21 | +@ToString(callSuper = true) | |
| 22 | +@Builder | |
| 23 | +@NoArgsConstructor | |
| 24 | +@AllArgsConstructor | |
| 25 | +public class MesWmItemConsumeLineDO extends BaseDO { | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 编号 | |
| 29 | + */ | |
| 30 | + @TableId | |
| 31 | + private Long id; | |
| 32 | + /** | |
| 33 | + * 消耗记录编号 | |
| 34 | + * | |
| 35 | + * 关联 {@link MesWmItemConsumeDO#getId()} | |
| 36 | + */ | |
| 37 | + private Long consumeId; | |
| 38 | + /** | |
| 39 | + * 物料编号 | |
| 40 | + * | |
| 41 | + * 关联 {@link MesMdItemDO#getId()} | |
| 42 | + */ | |
| 43 | + private Long itemId; | |
| 44 | + /** | |
| 45 | + * 消耗数量 | |
| 46 | + */ | |
| 47 | + private BigDecimal quantity; | |
| 48 | + /** | |
| 49 | + * 批次编号 | |
| 50 | + * | |
| 51 | + * 关联 {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO#getId()} | |
| 52 | + */ | |
| 53 | + private Long batchId; | |
| 54 | + /** | |
| 55 | + * 批次号 | |
| 56 | + * | |
| 57 | + * 冗余 {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO#getCode()} | |
| 58 | + */ | |
| 59 | + private String batchCode; | |
| 60 | + /** | |
| 61 | + * 备注 | |
| 62 | + */ | |
| 63 | + private String remark; | |
| 64 | + | |
| 65 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeLineMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | |
| 5 | +import org.apache.ibatis.annotations.Mapper; | |
| 6 | + | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * MES 物料消耗记录行 Mapper | |
| 11 | + * | |
| 12 | + * @author 芋道源码 | |
| 13 | + */ | |
| 14 | +@Mapper | |
| 15 | +public interface MesWmItemConsumeLineMapper extends BaseMapperX<MesWmItemConsumeLineDO> { | |
| 16 | + | |
| 17 | + default List<MesWmItemConsumeLineDO> selectListByConsumeId(Long consumeId) { | |
| 18 | + return selectList(MesWmItemConsumeLineDO::getConsumeId, consumeId); | |
| 19 | + } | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemconsume/MesWmItemConsumeMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | |
| 5 | +import org.apache.ibatis.annotations.Mapper; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * MES 物料消耗记录 Mapper | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +@Mapper | |
| 13 | +public interface MesWmItemConsumeMapper extends BaseMapperX<MesWmItemConsumeDO> { | |
| 14 | + | |
| 15 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| ... | ... | @@ -250,6 +250,7 @@ public interface ErrorCodeConstants { |
| 250 | 250 | ErrorCode PRO_FEEDBACK_TASK_OR_ORDER_FINISHED = new ErrorCode(1_040_506_009, "当前生产任务或工单已完成,不能继续报工"); |
| 251 | 251 | ErrorCode PRO_FEEDBACK_QUANTITY_MUST_POSITIVE = new ErrorCode(1_040_506_010, "报工数量必须大于 0"); |
| 252 | 252 | ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED = new ErrorCode(1_040_506_011, "请输入合格品和不良品数量,且合计须大于 0"); |
| 253 | + ErrorCode PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS = new ErrorCode(1_040_506_012, "当前报工单未完成检验(待检数量:{}),无法执行报工"); | |
| 253 | 254 | |
| 254 | 255 | // ========== MES 生产管理-生产流转卡(1-040-507-000) ========== |
| 255 | 256 | ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在"); | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.enums.wm; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | |
| 4 | +import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants; | |
| 5 | +import lombok.AllArgsConstructor; | |
| 6 | +import lombok.Getter; | |
| 7 | + | |
| 8 | +import java.util.Arrays; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * MES 物料消耗记录状态枚举 | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +@Getter | |
| 16 | +@AllArgsConstructor | |
| 17 | +public enum MesWmItemConsumeStatusEnum implements ArrayValuable<Integer> { | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 草稿 | |
| 21 | + */ | |
| 22 | + PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), | |
| 23 | + /** | |
| 24 | + * 已完成 | |
| 25 | + */ | |
| 26 | + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"); | |
| 27 | + | |
| 28 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemConsumeStatusEnum::getStatus).toArray(Integer[]::new); | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * 状态值 | |
| 32 | + */ | |
| 33 | + private final Integer status; | |
| 34 | + /** | |
| 35 | + * 状态名 | |
| 36 | + */ | |
| 37 | + private final String name; | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + public Integer[] array() { | |
| 41 | + return ARRAYS; | |
| 42 | + } | |
| 43 | + | |
| 44 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java
| ... | ... | @@ -68,10 +68,11 @@ public interface MesProFeedbackService { |
| 68 | 68 | /** |
| 69 | 69 | * 审批报工(审批中 -> 已完成 或 待检验) |
| 70 | 70 | * |
| 71 | - * @param id 编号 | |
| 71 | + * @param id 编号 | |
| 72 | + * @param userId 当前操作用户编号 | |
| 72 | 73 | * @return true=已完成, false=待检验 |
| 73 | 74 | */ |
| 74 | - boolean approveFeedback(Long id); | |
| 75 | + boolean approveFeedback(Long id, Long userId); | |
| 75 | 76 | |
| 76 | 77 | } |
| 77 | 78 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.pro.feedback; |
| 2 | 2 | |
| 3 | -import cn.hutool.core.util.BooleanUtil; | |
| 4 | 3 | import cn.hutool.core.util.ObjUtil; |
| 5 | 4 | import cn.hutool.core.util.ObjectUtil; |
| 6 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| ... | ... | @@ -9,6 +8,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedba |
| 9 | 8 | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; |
| 10 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; |
| 11 | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| 11 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | |
| 12 | 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; |
| 13 | 13 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper; |
| 14 | 14 | import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum; |
| ... | ... | @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationServic |
| 16 | 16 | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; |
| 17 | 17 | import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService; |
| 18 | 18 | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; |
| 19 | +import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService; | |
| 19 | 20 | import jakarta.annotation.Resource; |
| 20 | 21 | import org.springframework.context.annotation.Lazy; |
| 21 | 22 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -54,6 +55,9 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { |
| 54 | 55 | @Lazy // 避免循环依赖 |
| 55 | 56 | private MesProTaskService taskService; |
| 56 | 57 | |
| 58 | + @Resource | |
| 59 | + private MesWmItemConsumeService itemConsumeService; | |
| 60 | + | |
| 57 | 61 | @Override |
| 58 | 62 | public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { |
| 59 | 63 | // 1. 校验 |
| ... | ... | @@ -121,43 +125,55 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { |
| 121 | 125 | .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus())); |
| 122 | 126 | } |
| 123 | 127 | |
| 124 | - // DONE @AI:改成 boolean:true 表示已完成;false 表示待检验,前端需提示"报工成功,请等待质量检验完成!" | |
| 125 | 128 | @Override |
| 126 | 129 | @Transactional(rollbackFor = Exception.class) |
| 127 | - public boolean approveFeedback(Long id) { | |
| 128 | - // TODO @AI: 逻辑需要继续跟进; | |
| 129 | - // 1.1 校验存在 + 审批中状态 | |
| 130 | + public boolean approveFeedback(Long id, Long userId) { | |
| 131 | + // 1.1.a 校验存在 + 审批中状态 | |
| 130 | 132 | MesProFeedbackDO feedback = validateFeedbackStatusApproving(id); |
| 131 | - // 1.2 校验报工数量 > 0 | |
| 133 | + // 1.1.b 校验报工数量 > 0 | |
| 132 | 134 | if (feedback.getFeedbackQuantity() == null |
| 133 | 135 | || feedback.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { |
| 134 | 136 | throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE); |
| 135 | 137 | } |
| 136 | - // 1.3 校验任务未完成 | |
| 138 | + // 1.2.a 校验任务未完成 | |
| 137 | 139 | taskService.validateTaskNotFinished(feedback.getTaskId()); |
| 138 | - // 1.4 仍有待检数量时不能执行 | |
| 140 | + // 1.2.b 仍有待检数量时不能执行 | |
| 139 | 141 | if (feedback.getUncheckQuantity() != null |
| 140 | 142 | && feedback.getUncheckQuantity().compareTo(BigDecimal.ZERO) > 0) { |
| 141 | - throw exception(PRO_FEEDBACK_NOT_APPROVING); // TODO @芋艿:新增一个专用错误码,例如 PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS | |
| 143 | + throw exception(PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS, feedback.getUncheckQuantity()); | |
| 142 | 144 | } |
| 143 | 145 | |
| 144 | - // 2.1 查询工序的 checkFlag,决定目标状态 | |
| 145 | - boolean checkFlag = getCheckFlag(feedback.getRouteId(), feedback.getProcessId()); | |
| 146 | - Integer targetStatus = checkFlag | |
| 147 | - ? MesProFeedbackStatusEnum.UNCHECK.getStatus() // 需要检验 → 待检验 | |
| 148 | - : MesProFeedbackStatusEnum.FINISHED.getStatus(); // 无需检验 → 已完成 | |
| 149 | - // 2.2 更新状态 + 审核人 | |
| 150 | - feedbackMapper.updateById(new MesProFeedbackDO().setId(id) | |
| 151 | - .setStatus(targetStatus) | |
| 152 | - .setApproveUserId(getLoginUserId())); | |
| 153 | - | |
| 154 | - // 3. 如果不需要检验(直接完成),执行后续操作 | |
| 155 | - if (BooleanUtil.isFalse(checkFlag)) { | |
| 156 | - // TODO @芋艿:WM 物料消耗(WmItemConsumeService)未迁移,此处需补充物料消耗逻辑 | |
| 157 | - // TODO @芋艿:WM 产品产出(WmProductProduceService)未迁移,此处需补充产品产出逻辑 | |
| 158 | - // TODO @芋艿:updateProTaskAndWorkorder 待 pro_task 服务迁移后补充级联更新任务/工单的已生产数量 | |
| 146 | + // 2. 物料消耗:根据工序 BOM 生成消耗记录 | |
| 147 | + MesWmItemConsumeDO itemConsume = itemConsumeService.generateItemConsume(feedback); | |
| 148 | + if (itemConsume != null) { | |
| 149 | + itemConsumeService.finishItemConsume(itemConsume.getId()); | |
| 150 | + } | |
| 151 | + | |
| 152 | + // 3. 查询工序的 keyFlag + checkFlag | |
| 153 | + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( | |
| 154 | + feedback.getRouteId(), feedback.getProcessId()); | |
| 155 | + boolean keyFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getKeyFlag()); | |
| 156 | + boolean checkFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); | |
| 157 | + | |
| 158 | + // 4. 情况一:关键工序 + 需要检验 → 待检验状态(等质检完成后入库) | |
| 159 | + if (keyFlag && checkFlag) { | |
| 160 | + feedbackMapper.updateById(new MesProFeedbackDO().setId(id) | |
| 161 | + .setStatus(MesProFeedbackStatusEnum.UNCHECK.getStatus()) | |
| 162 | + .setApproveUserId(userId)); | |
| 163 | + // TODO @芋艿:WM 产品产出(WmProductProduceService)待补充 generateProductProduce(质量状态=待检验) | |
| 164 | + return false; | |
| 165 | + } | |
| 166 | + | |
| 167 | + // 4.1 情况二:关键工序 + 无需检验 → 直接完成 | |
| 168 | + if (keyFlag) { | |
| 169 | + // TODO @芋艿:WM 产品产出(WmProductProduceService)待补充 generateProductProduce + executeProductProduce | |
| 170 | + // TODO @芋艿:updateProTaskAndWorkorder 待补充级联更新任务/工单的已生产数量 | |
| 159 | 171 | } |
| 160 | - return BooleanUtil.isFalse(checkFlag); // true=已完成, false=待检验 | |
| 172 | + // 4.2 更新状态为已完成 + 审核人 | |
| 173 | + feedbackMapper.updateById(new MesProFeedbackDO().setId(id) | |
| 174 | + .setStatus(MesProFeedbackStatusEnum.FINISHED.getStatus()) | |
| 175 | + .setApproveUserId(userId)); | |
| 176 | + return true; // 已完成 | |
| 161 | 177 | } |
| 162 | 178 | |
| 163 | 179 | // ==================== 校验方法 ==================== |
| ... | ... | @@ -226,16 +242,4 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { |
| 226 | 242 | return taskService.validateTaskNotFinished(reqVO.getTaskId()); |
| 227 | 243 | } |
| 228 | 244 | |
| 229 | - /** | |
| 230 | - * 获取指定工艺路线中指定工序的 checkFlag | |
| 231 | - * | |
| 232 | - * @param routeId 工艺路线编号 | |
| 233 | - * @param processId 工序编号 | |
| 234 | - * @return 是否需要检验 | |
| 235 | - */ | |
| 236 | - private boolean getCheckFlag(Long routeId, Long processId) { | |
| 237 | - MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId); | |
| 238 | - return routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); | |
| 239 | - } | |
| 240 | - | |
| 241 | 245 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | |
| 4 | + | |
| 5 | +import java.util.List; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * MES 物料消耗记录行 Service 接口 | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +public interface MesWmItemConsumeLineService { | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * 批量创建消耗行 | |
| 16 | + * | |
| 17 | + * @param lines 消耗行列表 | |
| 18 | + */ | |
| 19 | + void createItemConsumeLineBatch(List<MesWmItemConsumeLineDO> lines); | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * 根据消耗记录编号查询消耗行 | |
| 23 | + * | |
| 24 | + * @param consumeId 消耗记录编号 | |
| 25 | + * @return 消耗行列表 | |
| 26 | + */ | |
| 27 | + List<MesWmItemConsumeLineDO> getItemConsumeLineListByConsumeId(Long consumeId); | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume.MesWmItemConsumeLineMapper; | |
| 5 | +import jakarta.annotation.Resource; | |
| 6 | +import org.springframework.stereotype.Service; | |
| 7 | +import org.springframework.validation.annotation.Validated; | |
| 8 | + | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * MES 物料消耗记录行 Service 实现类 | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +@Service | |
| 17 | +@Validated | |
| 18 | +public class MesWmItemConsumeLineServiceImpl implements MesWmItemConsumeLineService { | |
| 19 | + | |
| 20 | + @Resource | |
| 21 | + private MesWmItemConsumeLineMapper itemConsumeLineMapper; | |
| 22 | + | |
| 23 | + @Override | |
| 24 | + public void createItemConsumeLineBatch(List<MesWmItemConsumeLineDO> lines) { | |
| 25 | + itemConsumeLineMapper.insertBatch(lines); | |
| 26 | + } | |
| 27 | + | |
| 28 | + @Override | |
| 29 | + public List<MesWmItemConsumeLineDO> getItemConsumeLineListByConsumeId(Long consumeId) { | |
| 30 | + return itemConsumeLineMapper.selectListByConsumeId(consumeId); | |
| 31 | + } | |
| 32 | + | |
| 33 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * MES 物料消耗记录 Service 接口 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +public interface MesWmItemConsumeService { | |
| 12 | + | |
| 13 | + /** | |
| 14 | + * 根据报工单生成物料消耗记录 | |
| 15 | + * | |
| 16 | + * 1. 查询当前工序的 BOM 物料配置 | |
| 17 | + * 2. 生成消耗单头 + 行(消耗数量 = BOM 用料比例 × 报工数量) | |
| 18 | + * | |
| 19 | + * @param feedback 报工记录 | |
| 20 | + * @return 生成的消耗记录,无 BOM 时返回 null | |
| 21 | + */ | |
| 22 | + MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback); | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 完成物料消耗(库存扣减) | |
| 26 | + * | |
| 27 | + * 遍历消耗行,扣减线边库库存,更新消耗单状态为已完成 | |
| 28 | + * | |
| 29 | + * @param consumeId 消耗记录编号 | |
| 30 | + */ | |
| 31 | + void finishItemConsume(Long consumeId); | |
| 32 | + | |
| 33 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.itemconsume; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | |
| 5 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; | |
| 6 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | |
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO; | |
| 8 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemconsume.MesWmItemConsumeMapper; | |
| 9 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemConsumeStatusEnum; | |
| 10 | +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService; | |
| 11 | +import jakarta.annotation.Resource; | |
| 12 | +import org.springframework.stereotype.Service; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | + | |
| 15 | +import java.time.LocalDateTime; | |
| 16 | +import java.util.List; | |
| 17 | + | |
| 18 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 19 | + | |
| 20 | +/** | |
| 21 | + * MES 物料消耗记录 Service 实现类 | |
| 22 | + * | |
| 23 | + * 参考 KTG {@code WmItemConsumeServiceImpl#generateItemConsume} | |
| 24 | + * | |
| 25 | + * @author 芋道源码 | |
| 26 | + */ | |
| 27 | +@Service | |
| 28 | +@Validated | |
| 29 | +public class MesWmItemConsumeServiceImpl implements MesWmItemConsumeService { | |
| 30 | + | |
| 31 | + @Resource | |
| 32 | + private MesWmItemConsumeMapper itemConsumeMapper; | |
| 33 | + @Resource | |
| 34 | + private MesWmItemConsumeLineService itemConsumeLineService; | |
| 35 | + @Resource | |
| 36 | + private MesProRouteProductBomService routeProductBomService; | |
| 37 | + | |
| 38 | + // TODO @芋艿:待 MaterialStockService 补充 decreaseStock 后,注入并调用 | |
| 39 | + // @Resource | |
| 40 | + // private MesWmMaterialStockService materialStockService; | |
| 41 | + | |
| 42 | + @Override | |
| 43 | + public MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback) { | |
| 44 | + // 1. 查询当前工序的 BOM 物料配置 | |
| 45 | + List<MesProRouteProductBomDO> boms = routeProductBomService.getRouteProductBomList( | |
| 46 | + feedback.getRouteId(), feedback.getProcessId(), feedback.getItemId()); | |
| 47 | + if (CollUtil.isEmpty(boms)) { | |
| 48 | + return null; | |
| 49 | + } | |
| 50 | + | |
| 51 | + // 2.1 生成消耗单头 | |
| 52 | + MesWmItemConsumeDO consume = MesWmItemConsumeDO.builder() | |
| 53 | + .workOrderId(feedback.getWorkOrderId()).taskId(feedback.getTaskId()) | |
| 54 | + .workstationId(feedback.getWorkstationId()).processId(feedback.getProcessId()) | |
| 55 | + .feedbackId(feedback.getId()).consumeDate(LocalDateTime.now()) | |
| 56 | + .status(MesWmItemConsumeStatusEnum.PREPARE.getStatus()).build(); | |
| 57 | + itemConsumeMapper.insert(consume); | |
| 58 | + // 2.2 批量生成消耗行(消耗数量 = BOM 用料比例 × 报工数量) | |
| 59 | + List<MesWmItemConsumeLineDO> lines = convertList(boms, bom -> MesWmItemConsumeLineDO.builder() | |
| 60 | + .consumeId(consume.getId()).itemId(bom.getItemId()) | |
| 61 | + .quantity(bom.getQuantity().multiply(feedback.getFeedbackQuantity())).build()); | |
| 62 | + itemConsumeLineService.createItemConsumeLineBatch(lines); | |
| 63 | + return consume; | |
| 64 | + } | |
| 65 | + | |
| 66 | + @Override | |
| 67 | + public void finishItemConsume(Long consumeId) { | |
| 68 | + // TODO @芋艿:待 MaterialStockService 补充 decreaseStock 后实现库存扣减 | |
| 69 | + // List<MesWmItemConsumeLineDO> lines = itemConsumeLineService.getItemConsumeLineListByConsumeId(consumeId); | |
| 70 | + // for (MesWmItemConsumeLineDO line : lines) { | |
| 71 | + // materialStockService.decreaseStock(line.getItemId(), ..., line.getQuantity()); | |
| 72 | + // } | |
| 73 | + // 更新消耗单状态为已完成 | |
| 74 | + itemConsumeMapper.updateById(MesWmItemConsumeDO.builder() | |
| 75 | + .id(consumeId).status(MesWmItemConsumeStatusEnum.FINISHED.getStatus()).build()); | |
| 76 | + } | |
| 77 | + | |
| 78 | +} | ... | ... |