diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/MesWmProductionIssueController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/MesWmProductionIssueController.java index 6fd643d..d13234b 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/MesWmProductionIssueController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/MesWmProductionIssueController.java @@ -109,13 +109,40 @@ public class MesWmProductionIssueController { @PutMapping("/finish") @Operation(summary = "完成领料出库单") @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update-status')") + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:execute')") public CommonResult finishProductionIssue(@RequestParam("id") Long id) { issueService.finishProductionIssue(id); return success(true); } - // TODO @AI:check quantity + @PutMapping("/submit") + @Operation(summary = "提交领料出库单") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update')") + public CommonResult submitProductionIssue(@RequestParam("id") Long id) { + issueService.submitProductionIssue(id); + return success(true); + } + + @PutMapping("/stock") + @Operation(summary = "执行拣货") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update')") + public CommonResult stockProductionIssue(@RequestParam("id") Long id) { + issueService.stockProductionIssue(id); + return success(true); + } + + @PutMapping("/cancel") + @Operation(summary = "取消领料出库单") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update')") + public CommonResult cancelProductionIssue(@RequestParam("id") Long id) { + issueService.cancelProductionIssue(id); + return success(true); + } + + // TODO @AI:【芋艿】check quantity;晚点搞; // ==================== 拼接 VO ==================== @@ -127,15 +154,15 @@ public class MesWmProductionIssueController { Map workstationMap = workstationService.getWorkstationMap( convertSet(list, MesWmProductionIssueDO::getWorkstationId)); Map workOrderMap = workOrderService.getWorkOrderMap( - convertSet(list, MesWmProductionIssueDO::getWorkorderId)); + convertSet(list, MesWmProductionIssueDO::getWorkOrderId)); // 2. 构建结果 return BeanUtils.toBean(list, MesWmProductionIssueRespVO.class, vo -> { // 2.1 填充工作站名称 MapUtils.findAndThen(workstationMap, vo.getWorkstationId(), workstation -> vo.setWorkstationName(workstation.getName())); // 2.2 填充工单编号 - MapUtils.findAndThen(workOrderMap, vo.getWorkorderId(), - workOrder -> vo.setWorkorderCode(workOrder.getCode())); + MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(), + workOrder -> vo.setWorkOrderCode(workOrder.getCode())); }); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssuePageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssuePageReqVO.java index 98c1bc4..2c1b64f 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssuePageReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssuePageReqVO.java @@ -25,7 +25,7 @@ public class MesWmProductionIssuePageReqVO extends PageParam { private Long workstationId; @Schema(description = "生产工单ID", example = "1") - private Long workorderId; + private Long workOrderId; @Schema(description = "生产任务ID", example = "1") private Long taskId; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueRespVO.java index e9b05a5..a34af94 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueRespVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueRespVO.java @@ -25,10 +25,10 @@ public class MesWmProductionIssueRespVO { private String workstationName; @Schema(description = "生产工单 ID", example = "1") - private Long workorderId; + private Long workOrderId; @Schema(description = "生产工单编号", example = "WO20250226001") - private String workorderCode; + private String workOrderCode; @Schema(description = "生产任务 ID", example = "1") private Long taskId; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueSaveReqVO.java index b5c8aea..729b211 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueSaveReqVO.java @@ -23,11 +23,12 @@ public class MesWmProductionIssueSaveReqVO { private String name; @Schema(description = "工作站 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "工作站ID不能为空") + @NotNull(message = "工作站 ID 不能为空") private Long workstationId; - @Schema(description = "生产工单 ID", example = "1") - private Long workorderId; + @Schema(description = "生产工单 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "生产工单 ID 不能为空") + private Long workOrderId; @Schema(description = "需求时间", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "需求时间不能为空") diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/line/MesWmProductionIssueLineSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/line/MesWmProductionIssueLineSaveReqVO.java index 9643b5b..e903067 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/line/MesWmProductionIssueLineSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/line/MesWmProductionIssueLineSaveReqVO.java @@ -12,6 +12,9 @@ public class MesWmProductionIssueLineSaveReqVO { @Schema(description = "行ID", example = "1") private Long id; + @Schema(description = "领料单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long issueId; + @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long itemId; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDO.java index 2abfa8a..47481a1 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; @@ -13,12 +12,11 @@ import lombok.*; import java.time.LocalDateTime; -// TODO @AI:【需要一起讨论】不要直接改;是不是叫 issueheader 包?主要后续别的表也有 issue,希望区分下;还是加个合理的前缀?就像 wm_outsource_issue 这种; /** * MES 领料出库单 DO */ -@TableName("mes_wm_issue_header") -@KeySequence("mes_wm_issue_header_seq") +@TableName("mes_wm_production_issue") +@KeySequence("mes_wm_production_issue_seq") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -46,28 +44,20 @@ public class MesWmProductionIssueDO extends BaseDO { * 关联 {@link MesMdWorkstationDO#getId()} */ private Long workstationId; - // TODO @AI:workOrderId; /** * 生产工单 ID * * 关联 {@link MesProWorkOrderDO#getId()} */ - private Long workorderId; - // TODO @芋艿:【疑问】这个字段的来源? + private Long workOrderId; + // TODO @芋艿:【疑问,不要动】这个字段的来源? /** * 生产任务 ID * * 关联 {@link MesProTaskDO#getId()} */ private Long taskId; - // TODO @AI:应该不用记录?因为 workorderId 字段的; - /** - * 客户 ID - * - * 关联 {@link MesMdClientDO#getId()} - */ - private Long clientId; - // TODO @芋艿:【疑问】这个字段的更新时间; + // TODO @芋艿:【疑问,不要动】这个字段的更新时间; /** * 领料日期 */ @@ -86,21 +76,5 @@ public class MesWmProductionIssueDO extends BaseDO { * 备注 */ private String remark; - /** - * 预留字段 1 - */ - private String attribute1; - /** - * 预留字段 2 - */ - private String attribute2; - /** - * 预留字段 3 - */ - private Integer attribute3; - /** - * 预留字段 4 - */ - private Integer attribute4; } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDetailDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDetailDO.java index b03c7b4..e61b4f8 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDetailDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDetailDO.java @@ -16,8 +16,8 @@ import java.math.BigDecimal; /** * MES 领料出库明细 DO */ -@TableName("mes_wm_issue_detail") -@KeySequence("mes_wm_issue_detail_seq") +@TableName("mes_wm_production_issue_detail") +@KeySequence("mes_wm_production_issue_detail_seq") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -85,21 +85,5 @@ public class MesWmProductionIssueDetailDO extends BaseDO { * 备注 */ private String remark; - /** - * 预留字段1 - */ - private String attribute1; - /** - * 预留字段2 - */ - private String attribute2; - /** - * 预留字段3 - */ - private Integer attribute3; - /** - * 预留字段4 - */ - private Integer attribute4; } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueLineDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueLineDO.java index 1a405df..b0cf524 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueLineDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueLineDO.java @@ -12,8 +12,8 @@ import java.math.BigDecimal; /** * MES 领料出库单行 DO */ -@TableName("mes_wm_issue_line") -@KeySequence("mes_wm_issue_line_seq") +@TableName("mes_wm_production_issue_line") +@KeySequence("mes_wm_production_issue_line_seq") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -51,21 +51,5 @@ public class MesWmProductionIssueLineDO extends BaseDO { * 备注 */ private String remark; - /** - * 预留字段 1 - */ - private String attribute1; - /** - * 预留字段 2 - */ - private String attribute2; - /** - * 预留字段 3 - */ - private Integer attribute3; - /** - * 预留字段 4 - */ - private Integer attribute4; } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueDetailMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueDetailMapper.java index a36a8bc..c67bb74 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueDetailMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueDetailMapper.java @@ -16,6 +16,10 @@ public interface MesWmProductionIssueDetailMapper extends BaseMapperX selectListByIssueId(Long issueId) { + return selectList(MesWmProductionIssueDetailDO::getIssueId, issueId); + } + default void deleteByIssueId(Long issueId) { delete(MesWmProductionIssueDetailDO::getIssueId, issueId); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueMapper.java index 7699b98..0f0060d 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueMapper.java @@ -18,9 +18,7 @@ public interface MesWmProductionIssueMapper extends BaseMapperX { + /** + * 草稿 + * + * 对应方法:{@link MesWmProductionIssueService#createProductionIssue(MesWmProductionIssueSaveReqVO)} + */ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), - FINISHED(MesOrderStatusConstants.FINISHED, "已完成"); + /** + * 待拣货 + * + * 对应方法:{@link MesWmProductionIssueService#submitProductionIssue(Long)} + */ + APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"), + /** + * 待执行领出 + * + * 对应方法:{@link MesWmProductionIssueService#stockProductionIssue(Long)} + */ + APPROVED(MesOrderStatusConstants.APPROVED, "待执行领出"), + /** + * 已完成 + * + * 对应方法:{@link MesWmProductionIssueService#finishProductionIssue(Long)} + */ + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"), + /** + * 已取消 + * + * 对应方法:{@link MesWmProductionIssueService#cancelProductionIssue(Long)} + */ + CANCELED(MesOrderStatusConstants.CANCELLED, "已取消"); public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductionIssueStatusEnum::getStatus).toArray(Integer[]::new); /** - * 状态 + * 状态值 */ private final Integer status; /** diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailService.java index e4368c8..8251260 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailService.java @@ -50,6 +50,14 @@ public interface MesWmProductionIssueDetailService { List getProductionIssueDetailListByLineId(Long lineId); /** + * 根据领料单ID获取明细列表 + * + * @param issueId 领料单ID + * @return 明细列表 + */ + List getProductionIssueDetailListByIssueId(Long issueId); + + /** * 根据领料单ID删除明细 * * @param issueId 领料单ID diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailServiceImpl.java index 67be32d..b601d44 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailServiceImpl.java @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.detail.MesWmProductionIssueDetailSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDetailDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueDetailMapper; -import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; import jakarta.annotation.Resource; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -13,7 +13,6 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS; -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS; /** * MES 领料出库明细 Service 实现类 @@ -24,13 +23,15 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss @Resource private MesWmProductionIssueDetailMapper issueDetailMapper; + @Resource - private MesWmProductionIssueLineMapper issueLineMapper; + @Lazy + private MesWmProductionIssueLineService issueLineService; @Override public Long createProductionIssueDetail(MesWmProductionIssueDetailSaveReqVO createReqVO) { // 校验父数据存在 - validateParentIssueLineExists(createReqVO.getLineId()); + issueLineService.validateProductionIssueLineExists(createReqVO.getLineId()); // 插入 MesWmProductionIssueDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductionIssueDetailDO.class); @@ -41,9 +42,9 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss @Override public void updateProductionIssueDetail(MesWmProductionIssueDetailSaveReqVO updateReqVO) { // 校验存在 - validateIssueDetailExists(updateReqVO.getId()); + validateProductionIssueDetailExists(updateReqVO.getId()); // 校验父数据存在 - validateParentIssueLineExists(updateReqVO.getLineId()); + issueLineService.validateProductionIssueLineExists(updateReqVO.getLineId()); // 更新 MesWmProductionIssueDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductionIssueDetailDO.class); @@ -53,7 +54,7 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss @Override public void deleteProductionIssueDetail(Long id) { // 校验存在 - validateIssueDetailExists(id); + validateProductionIssueDetailExists(id); // 删除 issueDetailMapper.deleteById(id); } @@ -69,20 +70,19 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss } @Override + public List getProductionIssueDetailListByIssueId(Long issueId) { + return issueDetailMapper.selectListByIssueId(issueId); + } + + @Override public void deleteProductionIssueDetailByIssueId(Long issueId) { issueDetailMapper.deleteByIssueId(issueId); } - private void validateIssueDetailExists(Long id) { + private void validateProductionIssueDetailExists(Long id) { if (issueDetailMapper.selectById(id) == null) { throw exception(WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS); } } - private void validateParentIssueLineExists(Long lineId) { - if (issueLineMapper.selectById(lineId) == null) { - throw exception(WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS); - } - } - } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineService.java index 1e024a8..ca88cc9 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineService.java @@ -66,4 +66,12 @@ public interface MesWmProductionIssueLineService { */ void deleteProductionIssueLineByIssueId(Long issueId); + /** + * 校验领料出库单行是否存在 + * + * @param id 编号 + * @return 领料出库单行 + */ + MesWmProductionIssueLineDO validateProductionIssueLineExists(Long id); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java index 7874ab8..970676c 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java @@ -6,8 +6,9 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.M import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.MesWmProductionIssueLineSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; -import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueMapper; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import jakarta.annotation.Resource; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -15,7 +16,6 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS; -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_NOT_EXISTS; /** * MES 领料出库单行 Service 实现类 @@ -26,13 +26,19 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue @Resource private MesWmProductionIssueLineMapper issueLineMapper; + + @Resource + @Lazy + private MesWmProductionIssueService issueService; @Resource - private MesWmProductionIssueMapper issueMapper; + private MesMdItemService itemService; @Override public Long createProductionIssueLine(MesWmProductionIssueLineSaveReqVO createReqVO) { // 校验父数据存在 - validateParentIssueExists(createReqVO.getIssueId()); + issueService.validateProductionIssueExists(createReqVO.getIssueId()); + // 校验物料存在 + itemService.validateItemExists(createReqVO.getItemId()); // 插入 MesWmProductionIssueLineDO line = BeanUtils.toBean(createReqVO, MesWmProductionIssueLineDO.class); @@ -43,9 +49,11 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue @Override public void updateProductionIssueLine(MesWmProductionIssueLineSaveReqVO updateReqVO) { // 校验存在 - validateIssueLineExists(updateReqVO.getId()); + validateProductionIssueLineExists(updateReqVO.getId()); // 校验父数据存在 - validateParentIssueExists(updateReqVO.getIssueId()); + issueService.validateProductionIssueExists(updateReqVO.getIssueId()); + // 校验物料存在 + itemService.validateItemExists(updateReqVO.getItemId()); // 更新 MesWmProductionIssueLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductionIssueLineDO.class); @@ -55,7 +63,7 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue @Override public void deleteProductionIssueLine(Long id) { // 校验存在 - validateIssueLineExists(id); + validateProductionIssueLineExists(id); // 删除 issueLineMapper.deleteById(id); } @@ -80,16 +88,13 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue issueLineMapper.deleteByIssueId(issueId); } - private void validateIssueLineExists(Long id) { - if (issueLineMapper.selectById(id) == null) { + @Override + public MesWmProductionIssueLineDO validateProductionIssueLineExists(Long id) { + MesWmProductionIssueLineDO line = issueLineMapper.selectById(id); + if (line == null) { throw exception(WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS); } - } - - private void validateParentIssueExists(Long issueId) { - if (issueMapper.selectById(issueId) == null) { - throw exception(WM_PRODUCTION_ISSUE_NOT_EXISTS); - } + return line; } } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueService.java index 38cc6b3..8668053 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueService.java @@ -50,10 +50,39 @@ public interface MesWmProductionIssueService { PageResult getProductionIssuePage(MesWmProductionIssuePageReqVO pageReqVO); /** - * 完成领料出库单(草稿 → 已完成,执行出库) + * 校验领料出库单是否存在 + * + * @param id 编号 + * @return 领料出库单 + */ + MesWmProductionIssueDO validateProductionIssueExists(Long id); + + /** + * 提交领料出库单(草稿 → 待拣货) + * + * @param id 编号 + */ + void submitProductionIssue(Long id); + + /** + * 执行拣货(待拣货 → 待执行领出) + * + * @param id 编号 + */ + void stockProductionIssue(Long id); + + /** + * 执行领出/出库(待执行领出 → 已完成),更新库存台账 * * @param id 编号 */ void finishProductionIssue(Long id); + /** + * 取消领料出库单(任意非已完成/已取消状态 → 已取消) + * + * @param id 编号 + */ + void cancelProductionIssue(Long id); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueServiceImpl.java index 52ffa71..34e52ff 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueServiceImpl.java @@ -1,11 +1,16 @@ package cn.iocoder.yudao.module.mes.service.wm.productionissue; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssuePageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueMapper; import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductionIssueStatusEnum; import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; @@ -15,6 +20,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; +import java.util.List; + import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; @@ -41,9 +49,9 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ @Transactional(rollbackFor = Exception.class) public Long createProductionIssue(MesWmProductionIssueSaveReqVO createReqVO) { // 1. 校验关联数据 - workstationService.validateWorkstationExists(createReqVO.getWorkstationId()); - if (createReqVO.getWorkorderId() != null) { - workOrderService.validateWorkOrderExists(createReqVO.getWorkorderId()); + workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId()); + if (createReqVO.getWorkstationId() != null) { + workstationService.validateWorkstationExists(createReqVO.getWorkstationId()); } // 2. 插入主表 @@ -57,11 +65,11 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ @Transactional(rollbackFor = Exception.class) public void updateProductionIssue(MesWmProductionIssueSaveReqVO updateReqVO) { // 1.1 校验存在 + 准备中状态 - validateIssueExistsAndPrepare(updateReqVO.getId()); + validateProductionIssueExistsAndPrepare(updateReqVO.getId()); // 1.2 校验关联数据 - workstationService.validateWorkstationExists(updateReqVO.getWorkstationId()); - if (updateReqVO.getWorkorderId() != null) { - workOrderService.validateWorkOrderExists(updateReqVO.getWorkorderId()); + workOrderService.validateWorkOrderExists(updateReqVO.getWorkOrderId()); + if (updateReqVO.getWorkstationId() != null) { + workstationService.validateWorkstationExists(updateReqVO.getWorkstationId()); } // 2. 更新主表 @@ -73,7 +81,7 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ @Transactional(rollbackFor = Exception.class) public void deleteProductionIssue(Long id) { // 1. 校验存在 + 准备中状态 - validateIssueExistsAndPrepare(id); + validateProductionIssueExistsAndPrepare(id); // 2.1 级联删除明细 issueDetailService.deleteProductionIssueDetailByIssueId(id); @@ -95,21 +103,85 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ @Override @Transactional(rollbackFor = Exception.class) + public void submitProductionIssue(Long id) { + // 校验存在 + 草稿状态 + validateProductionIssueExistsAndPrepare(id); + // 校验至少有一条行 + List lines = issueLineService.getProductionIssueLineListByIssueId(id); + if (CollUtil.isEmpty(lines)) { + throw exception(WM_PRODUCTION_ISSUE_NO_LINE); + } + + // 提交(草稿 → 待拣货) + issueMapper.updateById(new MesWmProductionIssueDO() + .setId(id).setStatus(MesWmProductionIssueStatusEnum.APPROVING.getStatus())); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void stockProductionIssue(Long id) { + // 校验存在 + MesWmProductionIssueDO issue = validateProductionIssueExists(id); + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVING.getStatus(), issue.getStatus())) { + throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); + } + // 校验每行明细数量之和是否等于行领料数量 + List lines = issueLineService.getProductionIssueLineListByIssueId(id); + for (MesWmProductionIssueLineDO line : lines) { + List details = issueDetailService.getProductionIssueDetailListByLineId(line.getId()); + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details, + MesWmProductionIssueDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO); + if (line.getQuantity() != null && totalDetailQty.compareTo(line.getQuantity()) != 0) { + throw exception(WM_PRODUCTION_ISSUE_DETAIL_QUANTITY_MISMATCH); + } + } + + // 执行拣货(待拣货 → 待执行领出) + issueMapper.updateById(new MesWmProductionIssueDO() + .setId(id).setStatus(MesWmProductionIssueStatusEnum.APPROVED.getStatus())); + } + + @Override + @Transactional(rollbackFor = Exception.class) public void finishProductionIssue(Long id) { - // 1.1 校验存在 - MesWmProductionIssueDO issue = validateIssueExists(id); - // 1.2 校验状态:只有草稿才允许完成 - if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issue.getStatus())) { + // 校验存在 + MesWmProductionIssueDO issue = validateProductionIssueExists(id); + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVED.getStatus(), issue.getStatus())) { throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); } - // 2. 草稿 → 已完成 - // TODO @芋艿:库存扣减逻辑待完善(需要确定仓库ID的来源,可能需要在 line 或 detail 表中添加 warehouseId 字段) + // 遍历所有明细,更新库存台账(扣减库存) + // TODO @芋艿:【后续在弄】这里可能有点问题;缺少库存更新;后面在弄; + List details = issueDetailService.getProductionIssueDetailListByIssueId(id); + for (MesWmProductionIssueDetailDO detail : details) { + // materialStockService.decreaseStock( + // detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(), + // detail.getBatchId(), detail.getQuantity(), issue.getWorkOrderId(), null, null); + } + + // 更新出库单状态 issueMapper.updateById(new MesWmProductionIssueDO() .setId(id).setStatus(MesWmProductionIssueStatusEnum.FINISHED.getStatus())); } - private MesWmProductionIssueDO validateIssueExists(Long id) { + @Override + @Transactional(rollbackFor = Exception.class) + public void cancelProductionIssue(Long id) { + // 校验存在 + MesWmProductionIssueDO issue = validateProductionIssueExists(id); + // 已完成和已取消不允许取消 + if (ObjectUtils.equalsAny(issue.getStatus(), + MesWmProductionIssueStatusEnum.FINISHED.getStatus(), + MesWmProductionIssueStatusEnum.CANCELED.getStatus())) { + throw exception(WM_PRODUCTION_ISSUE_CANCEL_NOT_ALLOWED); + } + // 取消 + issueMapper.updateById(new MesWmProductionIssueDO() + .setId(id).setStatus(MesWmProductionIssueStatusEnum.CANCELED.getStatus())); + } + + @Override + public MesWmProductionIssueDO validateProductionIssueExists(Long id) { MesWmProductionIssueDO issue = issueMapper.selectById(id); if (issue == null) { throw exception(WM_PRODUCTION_ISSUE_NOT_EXISTS); @@ -120,8 +192,8 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ /** * 校验领料出库单存在且为准备中状态 */ - private MesWmProductionIssueDO validateIssueExistsAndPrepare(Long id) { - MesWmProductionIssueDO issue = validateIssueExists(id); + private MesWmProductionIssueDO validateProductionIssueExistsAndPrepare(Long id) { + MesWmProductionIssueDO issue = validateProductionIssueExists(id); if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issue.getStatus())) { throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); }