Commit 6ccf334c71110d7833090cb9a452e1b1f0489090
1 parent
6f68fd61
✨ feat(wm): 新增库存记录编号字段及相关校验
在多个请求对象中新增库存记录编号字段,并在相关服务中实现校验逻辑,以确保库存记录的有效性和一致性。这将增强库存管理的准确性,避免潜在的错误提交。 - MesWmProductIssueDetailSaveReqVO.java: 新增 materialStockId 字段 - MesWmReturnIssueDetailSaveReqVO.java: 新增 materialStockId 字段 - MesWmMaterialStockService.java: 新增 validateSelectedStock 方法 - MesWmMaterialStockServiceImpl.java: 实现 validateSelectedStock 方法 - MesWmProductIssueDetailServiceImpl.java: 更新校验逻辑以使用库存记录 - MesWmReturnIssueDetailServiceImpl.java: 更新校验逻辑以使用库存记录 - MesWmOutsourceIssueDetailServiceImpl.java: 更新校验逻辑以使用库存记录 - MesWmProductSalesDetailServiceImpl.java: 更新校验逻辑以使用库存记录 - MesWmReturnVendorDetailServiceImpl.java: 更新校验逻辑以使用库存记录
Showing
25 changed files
with
414 additions
and
57 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/detail/MesWmProductIssueDetailSaveReqVO.java
| @@ -26,6 +26,9 @@ public class MesWmProductIssueDetailSaveReqVO { | @@ -26,6 +26,9 @@ public class MesWmProductIssueDetailSaveReqVO { | ||
| 26 | @NotNull(message = "物料编号不能为空") | 26 | @NotNull(message = "物料编号不能为空") |
| 27 | private Long itemId; | 27 | private Long itemId; |
| 28 | 28 | ||
| 29 | + @Schema(description = "库存记录编号", example = "1") | ||
| 30 | + private Long materialStockId; | ||
| 31 | + | ||
| 29 | @Schema(description = "领料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "300.00") | 32 | @Schema(description = "领料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "300.00") |
| 30 | @NotNull(message = "领料数量不能为空") | 33 | @NotNull(message = "领料数量不能为空") |
| 31 | @DecimalMin(value = "0", inclusive = false, message = "领料数量必须大于 0") | 34 | @DecimalMin(value = "0", inclusive = false, message = "领料数量必须大于 0") |
| @@ -49,4 +52,4 @@ public class MesWmProductIssueDetailSaveReqVO { | @@ -49,4 +52,4 @@ public class MesWmProductIssueDetailSaveReqVO { | ||
| 49 | @Schema(description = "备注", example = "备注") | 52 | @Schema(description = "备注", example = "备注") |
| 50 | private String remark; | 53 | private String remark; |
| 51 | 54 | ||
| 52 | - } | 55 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/detail/MesWmReturnIssueDetailSaveReqVO.java
| @@ -26,6 +26,9 @@ public class MesWmReturnIssueDetailSaveReqVO { | @@ -26,6 +26,9 @@ public class MesWmReturnIssueDetailSaveReqVO { | ||
| 26 | @NotNull(message = "物料编号不能为空") | 26 | @NotNull(message = "物料编号不能为空") |
| 27 | private Long itemId; | 27 | private Long itemId; |
| 28 | 28 | ||
| 29 | + @Schema(description = "库存记录编号", example = "1") | ||
| 30 | + private Long materialStockId; | ||
| 31 | + | ||
| 29 | @Schema(description = "退料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "300.00") | 32 | @Schema(description = "退料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "300.00") |
| 30 | @NotNull(message = "退料数量不能为空") | 33 | @NotNull(message = "退料数量不能为空") |
| 31 | @DecimalMin(value = "0", inclusive = false, message = "退料数量必须大于0") | 34 | @DecimalMin(value = "0", inclusive = false, message = "退料数量必须大于0") |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| @@ -91,6 +91,7 @@ public interface ErrorCodeConstants { | @@ -91,6 +91,7 @@ public interface ErrorCodeConstants { | ||
| 91 | ErrorCode MD_PRODUCT_BOM_NOT_EXISTS = new ErrorCode(1_040_107_000, "产品BOM不存在"); | 91 | ErrorCode MD_PRODUCT_BOM_NOT_EXISTS = new ErrorCode(1_040_107_000, "产品BOM不存在"); |
| 92 | ErrorCode MD_PRODUCT_BOM_SELF_REFERENCE = new ErrorCode(1_040_107_001, "产品不能作为自身的BOM物料"); | 92 | ErrorCode MD_PRODUCT_BOM_SELF_REFERENCE = new ErrorCode(1_040_107_001, "产品不能作为自身的BOM物料"); |
| 93 | ErrorCode MD_PRODUCT_BOM_CIRCULAR = new ErrorCode(1_040_107_002, "BOM物料存在闭环,无法新增"); | 93 | ErrorCode MD_PRODUCT_BOM_CIRCULAR = new ErrorCode(1_040_107_002, "BOM物料存在闭环,无法新增"); |
| 94 | + ErrorCode MD_PRODUCT_BOM_ITEM_INVALID = new ErrorCode(1_040_107_003, "选择的 BOM 物料不属于当前产品"); | ||
| 94 | 95 | ||
| 95 | // ========== MES 基础数据-产品SOP(1-040-108-000) ========== | 96 | // ========== MES 基础数据-产品SOP(1-040-108-000) ========== |
| 96 | ErrorCode MD_PRODUCT_SOP_NOT_EXISTS = new ErrorCode(1_040_108_000, "产品SOP不存在"); | 97 | ErrorCode MD_PRODUCT_SOP_NOT_EXISTS = new ErrorCode(1_040_108_000, "产品SOP不存在"); |
| @@ -167,6 +168,7 @@ public interface ErrorCodeConstants { | @@ -167,6 +168,7 @@ public interface ErrorCodeConstants { | ||
| 167 | ErrorCode DV_CHECK_PLAN_NO_MACHINERY = new ErrorCode(1_040_302_003, "启用方案时,至少需要关联一台设备"); | 168 | ErrorCode DV_CHECK_PLAN_NO_MACHINERY = new ErrorCode(1_040_302_003, "启用方案时,至少需要关联一台设备"); |
| 168 | ErrorCode DV_CHECK_PLAN_NO_SUBJECT = new ErrorCode(1_040_302_004, "启用方案时,至少需要关联一个点检保养项目"); | 169 | ErrorCode DV_CHECK_PLAN_NO_SUBJECT = new ErrorCode(1_040_302_004, "启用方案时,至少需要关联一个点检保养项目"); |
| 169 | ErrorCode DV_CHECK_PLAN_NOT_ENABLED = new ErrorCode(1_040_302_005, "点检保养方案未启用,不允许停用"); | 170 | ErrorCode DV_CHECK_PLAN_NOT_ENABLED = new ErrorCode(1_040_302_005, "点检保养方案未启用,不允许停用"); |
| 171 | + ErrorCode DV_CHECK_PLAN_TYPE_MISMATCH = new ErrorCode(1_040_302_006, "点检保养方案类型与当前业务不匹配"); | ||
| 170 | // ========== MES 设备管理-点检方案设备(1-040-302-100) ========== | 172 | // ========== MES 设备管理-点检方案设备(1-040-302-100) ========== |
| 171 | ErrorCode DV_CHECK_PLAN_MACHINERY_NOT_EXISTS = new ErrorCode(1_040_302_100, "点检保养方案设备不存在"); | 173 | ErrorCode DV_CHECK_PLAN_MACHINERY_NOT_EXISTS = new ErrorCode(1_040_302_100, "点检保养方案设备不存在"); |
| 172 | ErrorCode DV_CHECK_PLAN_MACHINERY_DUPLICATE = new ErrorCode(1_040_302_101, "该设备已关联到当前方案,请勿重复添加"); | 174 | ErrorCode DV_CHECK_PLAN_MACHINERY_DUPLICATE = new ErrorCode(1_040_302_101, "该设备已关联到当前方案,请勿重复添加"); |
| @@ -241,11 +243,17 @@ public interface ErrorCodeConstants { | @@ -241,11 +243,17 @@ public interface ErrorCodeConstants { | ||
| 241 | ErrorCode PRO_WORK_ORDER_NOT_PREPARE = new ErrorCode(1_040_502_002, "只有草稿状态的工单才能执行此操作"); | 243 | ErrorCode PRO_WORK_ORDER_NOT_PREPARE = new ErrorCode(1_040_502_002, "只有草稿状态的工单才能执行此操作"); |
| 242 | ErrorCode PRO_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_502_003, "只有已确认状态的工单才能执行此操作"); | 244 | ErrorCode PRO_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_502_003, "只有已确认状态的工单才能执行此操作"); |
| 243 | ErrorCode PRO_WORK_ORDER_HAS_CHILDREN = new ErrorCode(1_040_502_004, "存在子工单,无法删除"); | 245 | ErrorCode PRO_WORK_ORDER_HAS_CHILDREN = new ErrorCode(1_040_502_004, "存在子工单,无法删除"); |
| 246 | + ErrorCode PRO_WORK_ORDER_PRODUCT_MISMATCH = new ErrorCode(1_040_502_005, "当前产品物料与生产工单产品不一致"); | ||
| 244 | ErrorCode PRO_WORK_ORDER_BOM_NOT_EXISTS = new ErrorCode(1_040_502_100, "生产工单BOM不存在"); | 247 | ErrorCode PRO_WORK_ORDER_BOM_NOT_EXISTS = new ErrorCode(1_040_502_100, "生产工单BOM不存在"); |
| 245 | 248 | ||
| 246 | // ========== MES 生产管理-生产任务(1-040-503-000) ========== | 249 | // ========== MES 生产管理-生产任务(1-040-503-000) ========== |
| 247 | ErrorCode PRO_TASK_NOT_EXISTS = new ErrorCode(1_040_503_000, "生产任务不存在"); | 250 | ErrorCode PRO_TASK_NOT_EXISTS = new ErrorCode(1_040_503_000, "生产任务不存在"); |
| 248 | ErrorCode PRO_TASK_ALREADY_FINISHED = new ErrorCode(1_040_503_001, "生产任务已完成或已取消,不能继续操作"); | 251 | ErrorCode PRO_TASK_ALREADY_FINISHED = new ErrorCode(1_040_503_001, "生产任务已完成或已取消,不能继续操作"); |
| 252 | + ErrorCode PRO_TASK_WORK_ORDER_MISMATCH = new ErrorCode(1_040_503_002, "生产任务不属于当前生产工单"); | ||
| 253 | + ErrorCode PRO_TASK_WORKSTATION_MISMATCH = new ErrorCode(1_040_503_003, "生产任务不属于当前工作站"); | ||
| 254 | + ErrorCode PRO_TASK_ROUTE_PROCESS_MISMATCH = new ErrorCode(1_040_503_004, "生产任务与当前工艺路线或工序不一致"); | ||
| 255 | + ErrorCode PRO_TASK_ITEM_MISMATCH = new ErrorCode(1_040_503_005, "生产任务产品与当前产品物料不一致"); | ||
| 256 | + ErrorCode PRO_WORKSTATION_PROCESS_MISMATCH = new ErrorCode(1_040_503_006, "工作站所属工序与当前工序不一致"); | ||
| 249 | // ========== MES 生产管理-生产任务投料(1-040-503-100) ========== | 257 | // ========== MES 生产管理-生产任务投料(1-040-503-100) ========== |
| 250 | ErrorCode PRO_TASK_ISSUE_NOT_EXISTS = new ErrorCode(1_040_503_100, "生产任务投料记录不存在"); | 258 | ErrorCode PRO_TASK_ISSUE_NOT_EXISTS = new ErrorCode(1_040_503_100, "生产任务投料记录不存在"); |
| 251 | 259 | ||
| @@ -399,6 +407,8 @@ public interface ErrorCodeConstants { | @@ -399,6 +407,8 @@ public interface ErrorCodeConstants { | ||
| 399 | ErrorCode WM_TRANSACTION_RELATED_NOT_EXISTS = new ErrorCode(1_040_703_010, "关联的库存事务不存在"); | 407 | ErrorCode WM_TRANSACTION_RELATED_NOT_EXISTS = new ErrorCode(1_040_703_010, "关联的库存事务不存在"); |
| 400 | ErrorCode WM_TRANSACTION_LIST_EMPTY = new ErrorCode(1_040_703_011, "库存事务列表不能为空"); | 408 | ErrorCode WM_TRANSACTION_LIST_EMPTY = new ErrorCode(1_040_703_011, "库存事务列表不能为空"); |
| 401 | ErrorCode WM_TRANSACTION_BATCH_NOT_EXISTS = new ErrorCode(1_040_703_012, "批次记录不存在"); | 409 | ErrorCode WM_TRANSACTION_BATCH_NOT_EXISTS = new ErrorCode(1_040_703_012, "批次记录不存在"); |
| 410 | + ErrorCode WM_MATERIAL_STOCK_REQUIRED = new ErrorCode(1_040_703_013, "库存记录不能为空"); | ||
| 411 | + ErrorCode WM_MATERIAL_STOCK_SELECTION_MISMATCH = new ErrorCode(1_040_703_014, "库存记录与提交的物料、批次或库位信息不一致"); | ||
| 402 | 412 | ||
| 403 | // ========== MES 仓库管理-到货通知单(1-040-704-000) ========== | 413 | // ========== MES 仓库管理-到货通知单(1-040-704-000) ========== |
| 404 | ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在"); | 414 | ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在"); |
| @@ -408,6 +418,7 @@ public interface ErrorCodeConstants { | @@ -408,6 +418,7 @@ public interface ErrorCodeConstants { | ||
| 408 | ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_RECEIPT = new ErrorCode(1_040_704_004, "只有待入库状态才允许完成"); | 418 | ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_RECEIPT = new ErrorCode(1_040_704_004, "只有待入库状态才允许完成"); |
| 409 | ErrorCode WM_ARRIVAL_NOTICE_IQC_PENDING = new ErrorCode(1_040_704_005, "存在待检验行,无法审批通过"); | 419 | ErrorCode WM_ARRIVAL_NOTICE_IQC_PENDING = new ErrorCode(1_040_704_005, "存在待检验行,无法审批通过"); |
| 410 | ErrorCode WM_ARRIVAL_NOTICE_NO_LINE = new ErrorCode(1_040_704_006, "至少需要一条行项目"); | 420 | ErrorCode WM_ARRIVAL_NOTICE_NO_LINE = new ErrorCode(1_040_704_006, "至少需要一条行项目"); |
| 421 | + ErrorCode WM_ARRIVAL_NOTICE_VENDOR_MISMATCH = new ErrorCode(1_040_704_007, "到货通知单的供应商与当前单据不一致"); | ||
| 411 | ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在"); | 422 | ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在"); |
| 412 | ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_MATCH = new ErrorCode(1_040_704_101, "到货通知单行不属于指定的到货通知单"); | 423 | ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_MATCH = new ErrorCode(1_040_704_101, "到货通知单行不属于指定的到货通知单"); |
| 413 | 424 | ||
| @@ -444,6 +455,8 @@ public interface ErrorCodeConstants { | @@ -444,6 +455,8 @@ public interface ErrorCodeConstants { | ||
| 444 | ErrorCode WM_OUTSOURCE_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_707_100, "外协发料单行不存在"); | 455 | ErrorCode WM_OUTSOURCE_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_707_100, "外协发料单行不存在"); |
| 445 | ErrorCode WM_OUTSOURCE_ISSUE_LINE_ITEM_NOT_IN_BOM = new ErrorCode(1_040_707_101, "发料单行对应的物料不在当前工单的 BOM 列表中"); | 456 | ErrorCode WM_OUTSOURCE_ISSUE_LINE_ITEM_NOT_IN_BOM = new ErrorCode(1_040_707_101, "发料单行对应的物料不在当前工单的 BOM 列表中"); |
| 446 | ErrorCode WM_OUTSOURCE_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_707_200, "外协发料单明细不存在"); | 457 | ErrorCode WM_OUTSOURCE_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_707_200, "外协发料单明细不存在"); |
| 458 | + ErrorCode WM_OUTSOURCE_ISSUE_DETAIL_LINE_NOT_MATCH = new ErrorCode(1_040_707_201, "拣货明细不属于指定的外协发料单"); | ||
| 459 | + ErrorCode WM_OUTSOURCE_ISSUE_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_707_202, "拣货明细的物料与外协发料单行的物料不一致"); | ||
| 447 | ErrorCode WM_OUTSOURCE_ISSUE_WORK_ORDER_TYPE_INVALID = new ErrorCode(1_040_707_008, "工单类型不是外协(代工)类型"); | 460 | ErrorCode WM_OUTSOURCE_ISSUE_WORK_ORDER_TYPE_INVALID = new ErrorCode(1_040_707_008, "工单类型不是外协(代工)类型"); |
| 448 | 461 | ||
| 449 | // ========== MES 仓库管理-生产领料出库单(1-040-708-000) ========== | 462 | // ========== MES 仓库管理-生产领料出库单(1-040-708-000) ========== |
| @@ -459,6 +472,7 @@ public interface ErrorCodeConstants { | @@ -459,6 +472,7 @@ public interface ErrorCodeConstants { | ||
| 459 | ErrorCode WM_PRODUCT_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_708_102, "领料出库单编码已存在"); | 472 | ErrorCode WM_PRODUCT_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_708_102, "领料出库单编码已存在"); |
| 460 | ErrorCode WM_PRODUCT_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_708_200, "生产领料出库单明细不存在"); | 473 | ErrorCode WM_PRODUCT_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_708_200, "生产领料出库单明细不存在"); |
| 461 | ErrorCode WM_PRODUCT_ISSUE_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_708_201, "拣货明细的物料与领料单行的物料不一致"); | 474 | ErrorCode WM_PRODUCT_ISSUE_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_708_201, "拣货明细的物料与领料单行的物料不一致"); |
| 475 | + ErrorCode WM_PRODUCT_ISSUE_DETAIL_LINE_NOT_MATCH = new ErrorCode(1_040_708_202, "拣货明细不属于指定的领料出库单"); | ||
| 462 | 476 | ||
| 463 | // ========== MES 仓库管理-生产入库单(1-040-709-000) ========== | 477 | // ========== MES 仓库管理-生产入库单(1-040-709-000) ========== |
| 464 | ErrorCode WM_PRODUCT_PRODUCE_NOT_EXISTS = new ErrorCode(1_040_709_000, "生产入库单不存在"); | 478 | ErrorCode WM_PRODUCT_PRODUCE_NOT_EXISTS = new ErrorCode(1_040_709_000, "生产入库单不存在"); |
| @@ -501,6 +515,8 @@ public interface ErrorCodeConstants { | @@ -501,6 +515,8 @@ public interface ErrorCodeConstants { | ||
| 501 | ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_710_201, "退料明细数量必须大于0"); | 515 | ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_710_201, "退料明细数量必须大于0"); |
| 502 | ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_710_202, "退料明细总数量不能超过退料单行数量"); | 516 | ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_710_202, "退料明细总数量不能超过退料单行数量"); |
| 503 | ErrorCode WM_RETURN_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_710_203, "退料单编码已存在"); | 517 | ErrorCode WM_RETURN_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_710_203, "退料单编码已存在"); |
| 518 | + ErrorCode WM_RETURN_ISSUE_DETAIL_LINE_NOT_MATCH = new ErrorCode(1_040_710_204, "退料明细不属于指定的退料单"); | ||
| 519 | + ErrorCode WM_RETURN_ISSUE_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_710_205, "退料明细的物料与退料单行的物料不一致"); | ||
| 504 | 520 | ||
| 505 | // ========== MES 仓库管理-供应商退货单(1-040-711-000) ========== | 521 | // ========== MES 仓库管理-供应商退货单(1-040-711-000) ========== |
| 506 | ErrorCode WM_RETURN_VENDOR_NOT_EXISTS = new ErrorCode(1_040_711_000, "供应商退货单不存在"); | 522 | ErrorCode WM_RETURN_VENDOR_NOT_EXISTS = new ErrorCode(1_040_711_000, "供应商退货单不存在"); |
| @@ -514,6 +530,7 @@ public interface ErrorCodeConstants { | @@ -514,6 +530,7 @@ public interface ErrorCodeConstants { | ||
| 514 | ErrorCode WM_RETURN_VENDOR_LINE_NOT_EXISTS = new ErrorCode(1_040_711_100, "供应商退货单行不存在"); | 530 | ErrorCode WM_RETURN_VENDOR_LINE_NOT_EXISTS = new ErrorCode(1_040_711_100, "供应商退货单行不存在"); |
| 515 | ErrorCode WM_RETURN_VENDOR_DETAIL_NOT_EXISTS = new ErrorCode(1_040_711_200, "供应商退货单明细不存在"); | 531 | ErrorCode WM_RETURN_VENDOR_DETAIL_NOT_EXISTS = new ErrorCode(1_040_711_200, "供应商退货单明细不存在"); |
| 516 | ErrorCode WM_RETURN_VENDOR_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_711_201, "退货明细数量必须大于 0"); | 532 | ErrorCode WM_RETURN_VENDOR_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_711_201, "退货明细数量必须大于 0"); |
| 533 | + ErrorCode WM_RETURN_VENDOR_DETAIL_LINE_NOT_MATCH = new ErrorCode(1_040_711_202, "拣货明细不属于指定的供应商退货单"); | ||
| 517 | 534 | ||
| 518 | // ========== MES 仓库管理-产品收货单(1-040-712-000) ========== | 535 | // ========== MES 仓库管理-产品收货单(1-040-712-000) ========== |
| 519 | ErrorCode WM_PRODUCT_RECPT_NOT_EXISTS = new ErrorCode(1_040_712_000, "产品收货单不存在"); | 536 | ErrorCode WM_PRODUCT_RECPT_NOT_EXISTS = new ErrorCode(1_040_712_000, "产品收货单不存在"); |
| @@ -588,6 +605,8 @@ public interface ErrorCodeConstants { | @@ -588,6 +605,8 @@ public interface ErrorCodeConstants { | ||
| 588 | ErrorCode WM_PRODUCT_SALES_DETAIL_NOT_EXISTS = new ErrorCode(1_040_714_012, "销售出库明细不存在"); | 605 | ErrorCode WM_PRODUCT_SALES_DETAIL_NOT_EXISTS = new ErrorCode(1_040_714_012, "销售出库明细不存在"); |
| 589 | ErrorCode WM_PRODUCT_SALES_STOCK_INSUFFICIENT = new ErrorCode(1_040_714_013, "库存不足,无法拣货"); | 606 | ErrorCode WM_PRODUCT_SALES_STOCK_INSUFFICIENT = new ErrorCode(1_040_714_013, "库存不足,无法拣货"); |
| 590 | ErrorCode WM_PRODUCT_SALES_LINE_QUANTITY_INVALID = new ErrorCode(1_040_714_014, "出库数量必须大于 0"); | 607 | ErrorCode WM_PRODUCT_SALES_LINE_QUANTITY_INVALID = new ErrorCode(1_040_714_014, "出库数量必须大于 0"); |
| 608 | + ErrorCode WM_PRODUCT_SALES_DETAIL_LINE_NOT_MATCH = new ErrorCode(1_040_714_015, "拣货明细不属于指定的销售出库单"); | ||
| 609 | + ErrorCode WM_PRODUCT_SALES_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_714_016, "拣货明细的物料与销售出库单行的物料不一致"); | ||
| 591 | 610 | ||
| 592 | // ========== MES 仓库管理-杂项出库单(1-040-715-000) ========== | 611 | // ========== MES 仓库管理-杂项出库单(1-040-715-000) ========== |
| 593 | ErrorCode WM_MISC_ISSUE_NOT_EXISTS = new ErrorCode(1_040_715_000, "杂项出库单不存在"); | 612 | ErrorCode WM_MISC_ISSUE_NOT_EXISTS = new ErrorCode(1_040_715_000, "杂项出库单不存在"); |
| @@ -616,6 +635,8 @@ public interface ErrorCodeConstants { | @@ -616,6 +635,8 @@ public interface ErrorCodeConstants { | ||
| 616 | ErrorCode WM_SALES_NOTICE_CODE_DUPLICATE = new ErrorCode(1_040_720_001, "通知单编号重复"); | 635 | ErrorCode WM_SALES_NOTICE_CODE_DUPLICATE = new ErrorCode(1_040_720_001, "通知单编号重复"); |
| 617 | ErrorCode WM_SALES_NOTICE_STATUS_NOT_ALLOW_DELETE = new ErrorCode(1_040_720_002, "单据状态不允许删除"); | 636 | ErrorCode WM_SALES_NOTICE_STATUS_NOT_ALLOW_DELETE = new ErrorCode(1_040_720_002, "单据状态不允许删除"); |
| 618 | ErrorCode WM_SALES_NOTICE_STATUS_NOT_ALLOW_UPDATE = new ErrorCode(1_040_720_003, "单据状态不允许修改"); | 637 | ErrorCode WM_SALES_NOTICE_STATUS_NOT_ALLOW_UPDATE = new ErrorCode(1_040_720_003, "单据状态不允许修改"); |
| 638 | + ErrorCode WM_SALES_NOTICE_STATUS_NOT_APPROVED = new ErrorCode(1_040_720_004, "发货通知单不是待出库状态"); | ||
| 639 | + ErrorCode WM_SALES_NOTICE_CLIENT_MISMATCH = new ErrorCode(1_040_720_005, "发货通知单的客户与当前单据不一致"); | ||
| 619 | ErrorCode WM_SALES_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_720_010, "发货通知单行不存在"); | 640 | ErrorCode WM_SALES_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_720_010, "发货通知单行不存在"); |
| 620 | ErrorCode WM_SALES_NOTICE_LINE_EMPTY = new ErrorCode(1_040_720_011, "发货通知单行为空,不能提交"); | 641 | ErrorCode WM_SALES_NOTICE_LINE_EMPTY = new ErrorCode(1_040_720_011, "发货通知单行为空,不能提交"); |
| 621 | 642 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckPlanTypeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.enums.dv; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 4 | +import lombok.AllArgsConstructor; | ||
| 5 | +import lombok.Getter; | ||
| 6 | + | ||
| 7 | +import java.util.Arrays; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * MES 点检保养方案类型枚举 | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +@Getter | ||
| 15 | +@AllArgsConstructor | ||
| 16 | +public enum MesDvCheckPlanTypeEnum implements ArrayValuable<Integer> { | ||
| 17 | + | ||
| 18 | + CHECK(1, "点检"), | ||
| 19 | + MAINTENANCE(2, "保养"); | ||
| 20 | + | ||
| 21 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvCheckPlanTypeEnum::getType).toArray(Integer[]::new); | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 类型值 | ||
| 25 | + */ | ||
| 26 | + private final Integer type; | ||
| 27 | + /** | ||
| 28 | + * 类型名 | ||
| 29 | + */ | ||
| 30 | + private final String name; | ||
| 31 | + | ||
| 32 | + @Override | ||
| 33 | + public Integer[] array() { | ||
| 34 | + return ARRAYS; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanService.java
| @@ -63,6 +63,15 @@ public interface MesDvCheckPlanService { | @@ -63,6 +63,15 @@ public interface MesDvCheckPlanService { | ||
| 63 | void validateCheckPlanExists(Long id); | 63 | void validateCheckPlanExists(Long id); |
| 64 | 64 | ||
| 65 | /** | 65 | /** |
| 66 | + * 校验点检保养方案存在,且类型匹配 | ||
| 67 | + * | ||
| 68 | + * @param id 方案编号 | ||
| 69 | + * @param type 期望的方案类型 | ||
| 70 | + * @return 方案 | ||
| 71 | + */ | ||
| 72 | + MesDvCheckPlanDO validateCheckPlanExistsAndType(Long id, Integer type); | ||
| 73 | + | ||
| 74 | + /** | ||
| 66 | * 校验点检保养方案为草稿状态 | 75 | * 校验点检保养方案为草稿状态 |
| 67 | * | 76 | * |
| 68 | * @param planId 方案编号 | 77 | * @param planId 方案编号 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanServiceImpl.java
| @@ -149,6 +149,15 @@ public class MesDvCheckPlanServiceImpl implements MesDvCheckPlanService { | @@ -149,6 +149,15 @@ public class MesDvCheckPlanServiceImpl implements MesDvCheckPlanService { | ||
| 149 | return plan; | 149 | return plan; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | + @Override | ||
| 153 | + public MesDvCheckPlanDO validateCheckPlanExistsAndType(Long id, Integer type) { | ||
| 154 | + MesDvCheckPlanDO plan = doValidateCheckPlanExists(id); | ||
| 155 | + if (ObjUtil.notEqual(plan.getType(), type)) { | ||
| 156 | + throw exception(DV_CHECK_PLAN_TYPE_MISMATCH); | ||
| 157 | + } | ||
| 158 | + return plan; | ||
| 159 | + } | ||
| 160 | + | ||
| 152 | private void validateCheckPlanCodeUnique(Long id, String code) { | 161 | private void validateCheckPlanCodeUnique(Long id, String code) { |
| 153 | MesDvCheckPlanDO plan = checkPlanMapper.selectByCode(code); | 162 | MesDvCheckPlanDO plan = checkPlanMapper.selectByCode(code); |
| 154 | if (plan == null) { | 163 | if (plan == null) { |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordServiceImpl.java
| @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkplan.MesDvCheckPlanSub | @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkplan.MesDvCheckPlanSub | ||
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkrecord.MesDvCheckRecordDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkrecord.MesDvCheckRecordDO; |
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkrecord.MesDvCheckRecordLineDO; | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkrecord.MesDvCheckRecordLineDO; |
| 12 | import cn.iocoder.yudao.module.mes.enums.dv.MesDvCheckRecordStatusEnum; | 12 | import cn.iocoder.yudao.module.mes.enums.dv.MesDvCheckRecordStatusEnum; |
| 13 | +import cn.iocoder.yudao.module.mes.enums.dv.MesDvCheckPlanTypeEnum; | ||
| 13 | import cn.iocoder.yudao.module.mes.enums.dv.MesDvCheckResultEnum; | 14 | import cn.iocoder.yudao.module.mes.enums.dv.MesDvCheckResultEnum; |
| 14 | import cn.iocoder.yudao.module.mes.dal.mysql.dv.checkrecord.MesDvCheckRecordMapper; | 15 | import cn.iocoder.yudao.module.mes.dal.mysql.dv.checkrecord.MesDvCheckRecordMapper; |
| 15 | import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanService; | 16 | import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanService; |
| @@ -37,6 +38,7 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; | @@ -37,6 +38,7 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; | ||
| 37 | @Validated | 38 | @Validated |
| 38 | public class MesDvCheckRecordServiceImpl implements MesDvCheckRecordService { | 39 | public class MesDvCheckRecordServiceImpl implements MesDvCheckRecordService { |
| 39 | 40 | ||
| 41 | + | ||
| 40 | @Resource | 42 | @Resource |
| 41 | private MesDvCheckRecordMapper checkRecordMapper; | 43 | private MesDvCheckRecordMapper checkRecordMapper; |
| 42 | @Resource | 44 | @Resource |
| @@ -162,7 +164,7 @@ public class MesDvCheckRecordServiceImpl implements MesDvCheckRecordService { | @@ -162,7 +164,7 @@ public class MesDvCheckRecordServiceImpl implements MesDvCheckRecordService { | ||
| 162 | machineryService.validateMachineryExists(reqVO.getMachineryId()); | 164 | machineryService.validateMachineryExists(reqVO.getMachineryId()); |
| 163 | // 校验点检计划是否存在 | 165 | // 校验点检计划是否存在 |
| 164 | if (reqVO.getPlanId() != null) { | 166 | if (reqVO.getPlanId() != null) { |
| 165 | - checkPlanService.validateCheckPlanExists(reqVO.getPlanId()); | 167 | + checkPlanService.validateCheckPlanExistsAndType(reqVO.getPlanId(), MesDvCheckPlanTypeEnum.CHECK.getType()); |
| 166 | } | 168 | } |
| 167 | // 校验点检人是否存在 | 169 | // 校验点检人是否存在 |
| 168 | if (reqVO.getUserId() != null) { | 170 | if (reqVO.getUserId() != null) { |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordServiceImpl.java
| @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.dv.maintenrecord.MesDvMaintenR | @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.dv.maintenrecord.MesDvMaintenR | ||
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.maintenrecord.MesDvMaintenRecordLineDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.maintenrecord.MesDvMaintenRecordLineDO; |
| 11 | import cn.iocoder.yudao.module.mes.dal.mysql.dv.maintenrecord.MesDvMaintenRecordMapper; | 11 | import cn.iocoder.yudao.module.mes.dal.mysql.dv.maintenrecord.MesDvMaintenRecordMapper; |
| 12 | import cn.iocoder.yudao.module.mes.enums.dv.MesDvMaintenRecordStatusEnum; | 12 | import cn.iocoder.yudao.module.mes.enums.dv.MesDvMaintenRecordStatusEnum; |
| 13 | +import cn.iocoder.yudao.module.mes.enums.dv.MesDvCheckPlanTypeEnum; | ||
| 13 | import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanService; | 14 | import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanService; |
| 14 | import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService; | 15 | import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService; |
| 15 | import jakarta.annotation.Resource; | 16 | import jakarta.annotation.Resource; |
| @@ -100,7 +101,7 @@ public class MesDvMaintenRecordServiceImpl implements MesDvMaintenRecordService | @@ -100,7 +101,7 @@ public class MesDvMaintenRecordServiceImpl implements MesDvMaintenRecordService | ||
| 100 | machineryService.validateMachineryExists(reqVO.getMachineryId()); | 101 | machineryService.validateMachineryExists(reqVO.getMachineryId()); |
| 101 | // 校验保养计划是否存在 | 102 | // 校验保养计划是否存在 |
| 102 | if (reqVO.getPlanId() != null) { | 103 | if (reqVO.getPlanId() != null) { |
| 103 | - checkPlanService.validateCheckPlanExists(reqVO.getPlanId()); | 104 | + checkPlanService.validateCheckPlanExistsAndType(reqVO.getPlanId(), MesDvCheckPlanTypeEnum.MAINTENANCE.getType()); |
| 104 | } | 105 | } |
| 105 | } | 106 | } |
| 106 | 107 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/card/MesProCardServiceImpl.java
| @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 7 | import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardPageReqVO; | 7 | import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardPageReqVO; |
| 8 | import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardSaveReqVO; | 8 | import cn.iocoder.yudao.module.mes.controller.admin.pro.card.vo.MesProCardSaveReqVO; |
| 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.card.MesProCardDO; | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.card.MesProCardDO; |
| 10 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; | ||
| 10 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.card.MesProCardMapper; | 11 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.card.MesProCardMapper; |
| 11 | import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum; | 12 | import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum; |
| 12 | import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; | 13 | import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; |
| @@ -171,9 +172,12 @@ public class MesProCardServiceImpl implements MesProCardService { | @@ -171,9 +172,12 @@ public class MesProCardServiceImpl implements MesProCardService { | ||
| 171 | // 校验编码唯一 | 172 | // 校验编码唯一 |
| 172 | validateCardCodeUnique(reqVO.getId(), reqVO.getCode()); | 173 | validateCardCodeUnique(reqVO.getId(), reqVO.getCode()); |
| 173 | // 校验工单存在 | 174 | // 校验工单存在 |
| 174 | - workOrderService.validateWorkOrderExists(reqVO.getWorkOrderId()); | 175 | + MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId()); |
| 175 | // 校验物料存在 | 176 | // 校验物料存在 |
| 176 | itemService.validateItemExists(reqVO.getItemId()); | 177 | itemService.validateItemExists(reqVO.getItemId()); |
| 178 | + if (ObjUtil.notEqual(workOrder.getProductId(), reqVO.getItemId())) { | ||
| 179 | + throw exception(PRO_WORK_ORDER_PRODUCT_MISMATCH); | ||
| 180 | + } | ||
| 177 | } | 181 | } |
| 178 | 182 | ||
| 179 | } | 183 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java
| @@ -46,6 +46,14 @@ public interface MesProFeedbackService { | @@ -46,6 +46,14 @@ public interface MesProFeedbackService { | ||
| 46 | MesProFeedbackDO getFeedback(Long id); | 46 | MesProFeedbackDO getFeedback(Long id); |
| 47 | 47 | ||
| 48 | /** | 48 | /** |
| 49 | + * 校验生产报工存在 | ||
| 50 | + * | ||
| 51 | + * @param id 编号 | ||
| 52 | + * @return 生产报工 | ||
| 53 | + */ | ||
| 54 | + MesProFeedbackDO validateFeedbackExists(Long id); | ||
| 55 | + | ||
| 56 | + /** | ||
| 49 | * 获得生产报工分页 | 57 | * 获得生产报工分页 |
| 50 | * | 58 | * |
| 51 | * @param pageReqVO 分页查询 | 59 | * @param pageReqVO 分页查询 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
| @@ -4,11 +4,13 @@ import cn.hutool.core.util.ObjUtil; | @@ -4,11 +4,13 @@ import cn.hutool.core.util.ObjUtil; | ||
| 4 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; | ||
| 7 | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackPageReqVO; | 8 | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackPageReqVO; |
| 8 | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; | 9 | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; |
| 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; |
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; | 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; |
| 13 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; | ||
| 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; | 14 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO; |
| 13 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceDO; | 15 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceDO; |
| 14 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO; | 16 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO; |
| @@ -219,7 +221,8 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | @@ -219,7 +221,8 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | ||
| 219 | 221 | ||
| 220 | // ==================== 校验方法 ==================== | 222 | // ==================== 校验方法 ==================== |
| 221 | 223 | ||
| 222 | - private MesProFeedbackDO validateFeedbackExists(Long id) { | 224 | + @Override |
| 225 | + public MesProFeedbackDO validateFeedbackExists(Long id) { | ||
| 223 | MesProFeedbackDO feedback = feedbackMapper.selectById(id); | 226 | MesProFeedbackDO feedback = feedbackMapper.selectById(id); |
| 224 | if (feedback == null) { | 227 | if (feedback == null) { |
| 225 | throw exception(PRO_FEEDBACK_NOT_EXISTS); | 228 | throw exception(PRO_FEEDBACK_NOT_EXISTS); |
| @@ -251,7 +254,10 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | @@ -251,7 +254,10 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | ||
| 251 | */ | 254 | */ |
| 252 | private MesProTaskDO validateFeedbackData(MesProFeedbackSaveReqVO reqVO) { | 255 | private MesProTaskDO validateFeedbackData(MesProFeedbackSaveReqVO reqVO) { |
| 253 | // 1. 校验工作站存在 | 256 | // 1. 校验工作站存在 |
| 254 | - workstationService.validateWorkstationExists(reqVO.getWorkstationId()); | 257 | + MesMdWorkstationDO workstation = workstationService.validateWorkstationExists(reqVO.getWorkstationId()); |
| 258 | + if (ObjUtil.notEqual(workstation.getProcessId(), reqVO.getProcessId())) { | ||
| 259 | + throw exception(PRO_WORKSTATION_PROCESS_MISMATCH); | ||
| 260 | + } | ||
| 255 | 261 | ||
| 256 | // 2.1 校验工艺路线 + 工序配置有效 | 262 | // 2.1 校验工艺路线 + 工序配置有效 |
| 257 | MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( | 263 | MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( |
| @@ -277,10 +283,32 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | @@ -277,10 +283,32 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { | ||
| 277 | } | 283 | } |
| 278 | 284 | ||
| 279 | // 3. 校验工单已确认 | 285 | // 3. 校验工单已确认 |
| 280 | - workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId()); | 286 | + MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId()); |
| 287 | + if (ObjUtil.notEqual(workOrder.getProductId(), reqVO.getItemId())) { | ||
| 288 | + throw exception(PRO_WORK_ORDER_PRODUCT_MISMATCH); | ||
| 289 | + } | ||
| 281 | 290 | ||
| 282 | // 4. 校验任务存在且未终态(已完成/已取消),并返回任务用于冗余 itemId | 291 | // 4. 校验任务存在且未终态(已完成/已取消),并返回任务用于冗余 itemId |
| 283 | - return taskService.validateTaskNotFinished(reqVO.getTaskId()); | 292 | + MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId()); |
| 293 | + validateTaskRelation(task, workstation, workOrder, reqVO); | ||
| 294 | + return task; | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + private void validateTaskRelation(MesProTaskDO task, MesMdWorkstationDO workstation, | ||
| 298 | + MesProWorkOrderDO workOrder, MesProFeedbackSaveReqVO reqVO) { | ||
| 299 | + if (ObjUtil.notEqual(task.getWorkOrderId(), workOrder.getId())) { | ||
| 300 | + throw exception(PRO_TASK_WORK_ORDER_MISMATCH); | ||
| 301 | + } | ||
| 302 | + if (ObjUtil.notEqual(task.getWorkstationId(), workstation.getId())) { | ||
| 303 | + throw exception(PRO_TASK_WORKSTATION_MISMATCH); | ||
| 304 | + } | ||
| 305 | + if (ObjUtil.notEqual(task.getRouteId(), reqVO.getRouteId()) | ||
| 306 | + || ObjUtil.notEqual(task.getProcessId(), reqVO.getProcessId())) { | ||
| 307 | + throw exception(PRO_TASK_ROUTE_PROCESS_MISMATCH); | ||
| 308 | + } | ||
| 309 | + if (ObjUtil.notEqual(task.getItemId(), reqVO.getItemId())) { | ||
| 310 | + throw exception(PRO_TASK_ITEM_MISMATCH); | ||
| 311 | + } | ||
| 284 | } | 312 | } |
| 285 | 313 | ||
| 286 | @Override | 314 | @Override |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomServiceImpl.java
| 1 | package cn.iocoder.yudao.module.mes.service.pro.route; | 1 | package cn.iocoder.yudao.module.mes.service.pro.route; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.hutool.core.util.ObjUtil; | 4 | import cn.hutool.core.util.ObjUtil; |
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO; | 6 | import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO; |
| 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; | 7 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; |
| 7 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.route.MesProRouteProductBomMapper; | 8 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.route.MesProRouteProductBomMapper; |
| 9 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | ||
| 10 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdProductBomService; | ||
| 8 | import jakarta.annotation.Resource; | 11 | import jakarta.annotation.Resource; |
| 9 | import org.springframework.context.annotation.Lazy; | 12 | import org.springframework.context.annotation.Lazy; |
| 10 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| @@ -30,13 +33,16 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | @@ -30,13 +33,16 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | ||
| 30 | @Resource | 33 | @Resource |
| 31 | @Lazy | 34 | @Lazy |
| 32 | private MesProRouteService routeService; | 35 | private MesProRouteService routeService; |
| 36 | + @Resource | ||
| 37 | + private MesMdItemService itemService; | ||
| 38 | + @Resource | ||
| 39 | + private MesMdProductBomService productBomService; | ||
| 33 | 40 | ||
| 34 | @Override | 41 | @Override |
| 35 | public Long createRouteProductBom(MesProRouteProductBomSaveReqVO createReqVO) { | 42 | public Long createRouteProductBom(MesProRouteProductBomSaveReqVO createReqVO) { |
| 36 | - // 1.0 已启用的工艺路线,不允许操作 | ||
| 37 | - routeService.validateRouteNotEnable(createReqVO.getRouteId()); | ||
| 38 | - // 1.1 校验唯一性 | ||
| 39 | - validateBomUnique(null, createReqVO.getItemId(), createReqVO.getProcessId(), createReqVO.getProductId()); | 43 | + // 1. 校验数据 |
| 44 | + validateRouteProductBomSaveData(null, createReqVO); | ||
| 45 | + | ||
| 40 | // 2. 插入 | 46 | // 2. 插入 |
| 41 | MesProRouteProductBomDO routeProductBom = BeanUtils.toBean(createReqVO, MesProRouteProductBomDO.class); | 47 | MesProRouteProductBomDO routeProductBom = BeanUtils.toBean(createReqVO, MesProRouteProductBomDO.class); |
| 42 | routeProductBomMapper.insert(routeProductBom); | 48 | routeProductBomMapper.insert(routeProductBom); |
| @@ -45,13 +51,11 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | @@ -45,13 +51,11 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | ||
| 45 | 51 | ||
| 46 | @Override | 52 | @Override |
| 47 | public void updateRouteProductBom(MesProRouteProductBomSaveReqVO updateReqVO) { | 53 | public void updateRouteProductBom(MesProRouteProductBomSaveReqVO updateReqVO) { |
| 48 | - // 1.0 已启用的工艺路线,不允许操作 | ||
| 49 | - routeService.validateRouteNotEnable(updateReqVO.getRouteId()); | ||
| 50 | - // 1.1 校验存在 | 54 | + // 1. 校验存在 + 校验数据 |
| 51 | validateRouteProductBomExists(updateReqVO.getId()); | 55 | validateRouteProductBomExists(updateReqVO.getId()); |
| 52 | - // 1.2 校验唯一性 | ||
| 53 | - validateBomUnique(updateReqVO.getId(), updateReqVO.getItemId(), updateReqVO.getProcessId(), updateReqVO.getProductId()); | ||
| 54 | - // 3. 更新 | 56 | + validateRouteProductBomSaveData(updateReqVO.getId(), updateReqVO); |
| 57 | + | ||
| 58 | + // 2. 更新 | ||
| 55 | MesProRouteProductBomDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProductBomDO.class); | 59 | MesProRouteProductBomDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProductBomDO.class); |
| 56 | routeProductBomMapper.updateById(updateObj); | 60 | routeProductBomMapper.updateById(updateObj); |
| 57 | } | 61 | } |
| @@ -75,6 +79,21 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | @@ -75,6 +79,21 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | ||
| 75 | } | 79 | } |
| 76 | } | 80 | } |
| 77 | 81 | ||
| 82 | + /** | ||
| 83 | + * 校验保存时的关联数据 | ||
| 84 | + * | ||
| 85 | + * @param id 记录编号(新增时为 null) | ||
| 86 | + * @param reqVO 保存请求 | ||
| 87 | + */ | ||
| 88 | + private void validateRouteProductBomSaveData(Long id, MesProRouteProductBomSaveReqVO reqVO) { | ||
| 89 | + // 校验已启用的工艺路线,不允许操作 | ||
| 90 | + routeService.validateRouteNotEnable(reqVO.getRouteId()); | ||
| 91 | + // 校验唯一性 | ||
| 92 | + validateBomUnique(id, reqVO.getItemId(), reqVO.getProcessId(), reqVO.getProductId()); | ||
| 93 | + // 校验物料属于产品 BOM | ||
| 94 | + validateBomItemBelongsToProduct(reqVO.getProductId(), reqVO.getItemId()); | ||
| 95 | + } | ||
| 96 | + | ||
| 78 | private void validateBomUnique(Long id, Long itemId, Long processId, Long productId) { | 97 | private void validateBomUnique(Long id, Long itemId, Long processId, Long productId) { |
| 79 | MesProRouteProductBomDO existing = routeProductBomMapper.selectByUnique(itemId, processId, productId); | 98 | MesProRouteProductBomDO existing = routeProductBomMapper.selectByUnique(itemId, processId, productId); |
| 80 | if (existing == null) { | 99 | if (existing == null) { |
| @@ -85,6 +104,14 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | @@ -85,6 +104,14 @@ public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomSe | ||
| 85 | } | 104 | } |
| 86 | } | 105 | } |
| 87 | 106 | ||
| 107 | + private void validateBomItemBelongsToProduct(Long productId, Long itemId) { | ||
| 108 | + itemService.validateItemExists(itemId); | ||
| 109 | + if (!CollUtil.anyMatch(productBomService.getProductBomListByItemId(productId), | ||
| 110 | + productBom -> ObjUtil.equal(productBom.getBomItemId(), itemId))) { | ||
| 111 | + throw exception(MD_PRODUCT_BOM_ITEM_INVALID); | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | + | ||
| 88 | @Override | 115 | @Override |
| 89 | public MesProRouteProductBomDO getRouteProductBom(Long id) { | 116 | public MesProRouteProductBomDO getRouteProductBom(Long id) { |
| 90 | return routeProductBomMapper.selectById(id); | 117 | return routeProductBomMapper.selectById(id); |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderBomServiceImpl.java
| @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.bom.MesProW | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.bom.MesProW | ||
| 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdProductBomDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdProductBomDO; |
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO; | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO; |
| 12 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; | ||
| 12 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderBomMapper; | 13 | import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderBomMapper; |
| 13 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | 14 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 14 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdProductBomService; | 15 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdProductBomService; |
| @@ -25,6 +26,7 @@ import java.util.Set; | @@ -25,6 +26,7 @@ import java.util.Set; | ||
| 25 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 26 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 26 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 27 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 27 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MD_ITEM_NOT_EXISTS; | 28 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MD_ITEM_NOT_EXISTS; |
| 29 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MD_PRODUCT_BOM_ITEM_INVALID; | ||
| 28 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_WORK_ORDER_BOM_NOT_EXISTS; | 30 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_WORK_ORDER_BOM_NOT_EXISTS; |
| 29 | 31 | ||
| 30 | /** | 32 | /** |
| @@ -49,8 +51,8 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | @@ -49,8 +51,8 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | ||
| 49 | 51 | ||
| 50 | @Override | 52 | @Override |
| 51 | public Long createWorkOrderBom(MesProWorkOrderBomSaveReqVO createReqVO) { | 53 | public Long createWorkOrderBom(MesProWorkOrderBomSaveReqVO createReqVO) { |
| 52 | - // 校验工单存在 | ||
| 53 | - workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId()); | 54 | + // 校验数据 |
| 55 | + validateWorkOrderBomSaveData(createReqVO); | ||
| 54 | 56 | ||
| 55 | // 插入数据 | 57 | // 插入数据 |
| 56 | MesProWorkOrderBomDO workOrderBom = BeanUtils.toBean(createReqVO, MesProWorkOrderBomDO.class); | 58 | MesProWorkOrderBomDO workOrderBom = BeanUtils.toBean(createReqVO, MesProWorkOrderBomDO.class); |
| @@ -62,6 +64,8 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | @@ -62,6 +64,8 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | ||
| 62 | public void updateWorkOrderBom(MesProWorkOrderBomSaveReqVO updateReqVO) { | 64 | public void updateWorkOrderBom(MesProWorkOrderBomSaveReqVO updateReqVO) { |
| 63 | // 校验存在 | 65 | // 校验存在 |
| 64 | validateWorkOrderBomExists(updateReqVO.getId()); | 66 | validateWorkOrderBomExists(updateReqVO.getId()); |
| 67 | + // 校验数据 | ||
| 68 | + validateWorkOrderBomSaveData(updateReqVO); | ||
| 65 | 69 | ||
| 66 | // 更新数据 | 70 | // 更新数据 |
| 67 | MesProWorkOrderBomDO updateObj = BeanUtils.toBean(updateReqVO, MesProWorkOrderBomDO.class); | 71 | MesProWorkOrderBomDO updateObj = BeanUtils.toBean(updateReqVO, MesProWorkOrderBomDO.class); |
| @@ -83,6 +87,19 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | @@ -83,6 +87,19 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | ||
| 83 | } | 87 | } |
| 84 | } | 88 | } |
| 85 | 89 | ||
| 90 | + private void validateWorkOrderBomSaveData(MesProWorkOrderBomSaveReqVO reqVO) { | ||
| 91 | + // 校验工单存在 | ||
| 92 | + MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderExists(reqVO.getWorkOrderId()); | ||
| 93 | + // DONE @AI:增加注释 | ||
| 94 | + // 校验物料存在 | ||
| 95 | + itemService.validateItemExists(reqVO.getItemId()); | ||
| 96 | + // 校验物料属于产品 BOM | ||
| 97 | + if (!CollUtil.anyMatch(productBomService.getProductBomListByItemId(workOrder.getProductId()), | ||
| 98 | + productBom -> productBom.getBomItemId().equals(reqVO.getItemId()))) { | ||
| 99 | + throw exception(MD_PRODUCT_BOM_ITEM_INVALID); | ||
| 100 | + } | ||
| 101 | + } | ||
| 102 | + | ||
| 86 | @Override | 103 | @Override |
| 87 | public MesProWorkOrderBomDO getWorkOrderBom(Long id) { | 104 | public MesProWorkOrderBomDO getWorkOrderBom(Long id) { |
| 88 | return workOrderBomMapper.selectById(id); | 105 | return workOrderBomMapper.selectById(id); |
| @@ -133,4 +150,4 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | @@ -133,4 +150,4 @@ public class MesProWorkOrderBomServiceImpl implements MesProWorkOrderBomService | ||
| 133 | workOrderBomMapper.insertBatch(bomList); | 150 | workOrderBomMapper.insertBatch(bomList); |
| 134 | } | 151 | } |
| 135 | 152 | ||
| 136 | -} | ||
| 137 | \ No newline at end of file | 153 | \ No newline at end of file |
| 154 | +} |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java
| @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqV | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqV | ||
| 8 | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO; | 8 | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO; |
| 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; |
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; |
| 11 | +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; | ||
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; | 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; |
| 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; | 13 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; |
| 13 | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; | 14 | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; |
| @@ -23,6 +24,7 @@ import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationServic | @@ -23,6 +24,7 @@ import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationServic | ||
| 23 | import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService; | 24 | import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService; |
| 24 | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; | 25 | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; |
| 25 | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService; | 26 | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService; |
| 27 | +import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService; | ||
| 26 | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; | 28 | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; |
| 27 | import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; | 29 | import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; |
| 28 | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService; | 30 | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService; |
| @@ -76,6 +78,9 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { | @@ -76,6 +78,9 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { | ||
| 76 | @Resource | 78 | @Resource |
| 77 | @Lazy | 79 | @Lazy |
| 78 | private MesProRouteProcessService routeProcessService; | 80 | private MesProRouteProcessService routeProcessService; |
| 81 | + @Resource | ||
| 82 | + @Lazy | ||
| 83 | + private MesProTaskService taskService; | ||
| 79 | 84 | ||
| 80 | @Resource | 85 | @Resource |
| 81 | private AdminUserApi adminUserApi; | 86 | private AdminUserApi adminUserApi; |
| @@ -136,9 +141,39 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { | @@ -136,9 +141,39 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { | ||
| 136 | // 校验工位、检测人员存在 | 141 | // 校验工位、检测人员存在 |
| 137 | MesMdWorkstationDO workstation = workstationService.validateWorkstationExists(reqVO.getWorkstationId()); | 142 | MesMdWorkstationDO workstation = workstationService.validateWorkstationExists(reqVO.getWorkstationId()); |
| 138 | adminUserApi.validateUser(reqVO.getInspectorUserId()); | 143 | adminUserApi.validateUser(reqVO.getInspectorUserId()); |
| 144 | + // 校验工单存在 | ||
| 145 | + MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId()); | ||
| 146 | + if (reqVO.getItemId() != null && ObjUtil.notEqual(reqVO.getItemId(), workOrder.getProductId())) { | ||
| 147 | + throw exception(PRO_WORK_ORDER_PRODUCT_MISMATCH); | ||
| 148 | + } | ||
| 149 | + if (reqVO.getProcessId() != null && ObjUtil.notEqual(workstation.getProcessId(), reqVO.getProcessId())) { | ||
| 150 | + throw exception(PRO_WORKSTATION_PROCESS_MISMATCH); | ||
| 151 | + } | ||
| 152 | + // 校验任务关系(如果指定了任务) | ||
| 153 | + if (reqVO.getTaskId() != null) { | ||
| 154 | + MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId()); | ||
| 155 | + validateTaskRelation(task, workstation, workOrder, reqVO); | ||
| 156 | + } | ||
| 139 | return workstation; | 157 | return workstation; |
| 140 | } | 158 | } |
| 141 | 159 | ||
| 160 | + private void validateTaskRelation(MesProTaskDO task, MesMdWorkstationDO workstation, | ||
| 161 | + MesProWorkOrderDO workOrder, MesQcIpqcSaveReqVO reqVO) { | ||
| 162 | + if (ObjUtil.notEqual(task.getWorkOrderId(), workOrder.getId())) { | ||
| 163 | + throw exception(PRO_TASK_WORK_ORDER_MISMATCH); | ||
| 164 | + } | ||
| 165 | + if (ObjUtil.notEqual(task.getWorkstationId(), workstation.getId())) { | ||
| 166 | + throw exception(PRO_TASK_WORKSTATION_MISMATCH); | ||
| 167 | + } | ||
| 168 | + Long expectedProcessId = reqVO.getProcessId() != null ? reqVO.getProcessId() : workstation.getProcessId(); | ||
| 169 | + if (expectedProcessId != null && ObjUtil.notEqual(task.getProcessId(), expectedProcessId)) { | ||
| 170 | + throw exception(PRO_TASK_ROUTE_PROCESS_MISMATCH); | ||
| 171 | + } | ||
| 172 | + if (ObjUtil.notEqual(task.getItemId(), workOrder.getProductId())) { | ||
| 173 | + throw exception(PRO_TASK_ITEM_MISMATCH); | ||
| 174 | + } | ||
| 175 | + } | ||
| 176 | + | ||
| 142 | @Override | 177 | @Override |
| 143 | @Transactional(rollbackFor = Exception.class) | 178 | @Transactional(rollbackFor = Exception.class) |
| 144 | public void finishIpqc(Long id) { | 179 | public void finishIpqc(Long id) { |
| @@ -238,8 +273,8 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { | @@ -238,8 +273,8 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { | ||
| 238 | return null; | 273 | return null; |
| 239 | } | 274 | } |
| 240 | if (Objects.equals(sourceDocType, MesBizTypeConstants.PRO_FEEDBACK)) { | 275 | if (Objects.equals(sourceDocType, MesBizTypeConstants.PRO_FEEDBACK)) { |
| 241 | - MesProFeedbackDO feedback = feedbackService.getFeedback(sourceDocId); | ||
| 242 | - return feedback != null ? feedback.getCode() : null; | 276 | + MesProFeedbackDO feedback = feedbackService.validateFeedbackExists(sourceDocId); |
| 277 | + return feedback.getCode(); | ||
| 243 | } | 278 | } |
| 244 | return null; | 279 | return null; |
| 245 | } | 280 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
| @@ -8,11 +8,13 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | @@ -8,11 +8,13 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 8 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | 8 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 9 | import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptPageReqVO; | 9 | import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptPageReqVO; |
| 10 | import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptSaveReqVO; | 10 | import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptSaveReqVO; |
| 11 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO; | ||
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO; | 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO; |
| 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO; | 13 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO; |
| 13 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; | 14 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; |
| 14 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapper; | 15 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapper; |
| 15 | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; | 16 | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| 17 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmArrivalNoticeStatusEnum; | ||
| 16 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum; | 18 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum; |
| 17 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; | 19 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| 18 | import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService; | 20 | import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService; |
| @@ -90,7 +92,13 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { | @@ -90,7 +92,13 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { | ||
| 90 | vendorService.validateVendorExists(reqVO.getVendorId()); | 92 | vendorService.validateVendorExists(reqVO.getVendorId()); |
| 91 | // 校验到货通知单存在 | 93 | // 校验到货通知单存在 |
| 92 | if (reqVO.getNoticeId() != null) { | 94 | if (reqVO.getNoticeId() != null) { |
| 93 | - arrivalNoticeService.validateArrivalNoticeExists(reqVO.getNoticeId()); | 95 | + MesWmArrivalNoticeDO notice = arrivalNoticeService.validateArrivalNoticeExists(reqVO.getNoticeId()); |
| 96 | + if (ObjUtil.notEqual(notice.getStatus(), MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus())) { | ||
| 97 | + throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_RECEIPT); | ||
| 98 | + } | ||
| 99 | + if (ObjUtil.notEqual(notice.getVendorId(), reqVO.getVendorId())) { | ||
| 100 | + throw exception(WM_ARRIVAL_NOTICE_VENDOR_MISMATCH); | ||
| 101 | + } | ||
| 94 | } | 102 | } |
| 95 | // 校验来料检验单存在 | 103 | // 校验来料检验单存在 |
| 96 | if (reqVO.getIqcId() != null) { | 104 | if (reqVO.getIqcId() != null) { |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java
| @@ -132,4 +132,20 @@ public interface MesWmMaterialStockService { | @@ -132,4 +132,20 @@ public interface MesWmMaterialStockService { | ||
| 132 | */ | 132 | */ |
| 133 | void checkAreaMixingRule(Long areaId, Long itemId, Long batchId); | 133 | void checkAreaMixingRule(Long areaId, Long itemId, Long batchId); |
| 134 | 134 | ||
| 135 | + /** | ||
| 136 | + * 校验前端选择的库存记录,兜底避免串单或越权提交 | ||
| 137 | + * | ||
| 138 | + * @param materialStockId 库存记录编号 | ||
| 139 | + * @param itemId 物料编号 | ||
| 140 | + * @param batchId 批次编号 | ||
| 141 | + * @param batchCode 批次号(可选) | ||
| 142 | + * @param warehouseId 仓库编号 | ||
| 143 | + * @param locationId 库区编号 | ||
| 144 | + * @param areaId 库位编号 | ||
| 145 | + * @param quantity 数量(可选,校验库存充足) | ||
| 146 | + * @return 校验通过的库存记录 | ||
| 147 | + */ | ||
| 148 | + MesWmMaterialStockDO validateSelectedStock(Long materialStockId, Long itemId, Long batchId, String batchCode, | ||
| 149 | + Long warehouseId, Long locationId, Long areaId, BigDecimal quantity); | ||
| 150 | + | ||
| 135 | } | 151 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
| @@ -185,4 +185,34 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService | @@ -185,4 +185,34 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService | ||
| 185 | } | 185 | } |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | + @Override | ||
| 189 | + public MesWmMaterialStockDO validateSelectedStock(Long materialStockId, | ||
| 190 | + Long itemId, | ||
| 191 | + Long batchId, | ||
| 192 | + String batchCode, | ||
| 193 | + Long warehouseId, | ||
| 194 | + Long locationId, | ||
| 195 | + Long areaId, | ||
| 196 | + BigDecimal quantity) { | ||
| 197 | + // 1. 校验库存记录必须存在 | ||
| 198 | + if (materialStockId == null) { | ||
| 199 | + throw exception(WM_MATERIAL_STOCK_REQUIRED); | ||
| 200 | + } | ||
| 201 | + MesWmMaterialStockDO stock = validateMaterialStockExists(materialStockId); | ||
| 202 | + // 2. 校验库存记录的物料、批次、仓库、库区、库位等信息与前端选择的一致,避免串单或越权提交 | ||
| 203 | + if (ObjUtil.notEqual(stock.getItemId(), itemId) | ||
| 204 | + || ObjUtil.notEqual(stock.getBatchId(), batchId) | ||
| 205 | + || (batchCode != null && ObjUtil.notEqual(stock.getBatchCode(), batchCode)) | ||
| 206 | + || ObjUtil.notEqual(stock.getWarehouseId(), warehouseId) | ||
| 207 | + || ObjUtil.notEqual(stock.getLocationId(), locationId) | ||
| 208 | + || ObjUtil.notEqual(stock.getAreaId(), areaId)) { | ||
| 209 | + throw exception(WM_MATERIAL_STOCK_SELECTION_MISMATCH); | ||
| 210 | + } | ||
| 211 | + // 3. 校验库存数量充足(如果前端传了 quantity,则必须保证库存数量 >= quantity) | ||
| 212 | + if (quantity != null && stock.getQuantity() != null && stock.getQuantity().compareTo(quantity) < 0) { | ||
| 213 | + throw exception(WM_MATERIAL_STOCK_INSUFFICIENT); | ||
| 214 | + } | ||
| 215 | + return stock; | ||
| 216 | + } | ||
| 217 | + | ||
| 188 | } | 218 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourceissue/MesWmOutsourceIssueDetailServiceImpl.java
| 1 | package cn.iocoder.yudao.module.mes.service.wm.outsourceissue; | 1 | package cn.iocoder.yudao.module.mes.service.wm.outsourceissue; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.ObjUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 4 | import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourceissue.vo.detail.MesWmOutsourceIssueDetailSaveReqVO; | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourceissue.vo.detail.MesWmOutsourceIssueDetailSaveReqVO; |
| 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueDetailDO; | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueDetailDO; |
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueLineDO; | ||
| 6 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourceissue.MesWmOutsourceIssueDetailMapper; | 8 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourceissue.MesWmOutsourceIssueDetailMapper; |
| 7 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | 9 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 10 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | ||
| 11 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | ||
| 8 | import jakarta.annotation.Resource; | 12 | import jakarta.annotation.Resource; |
| 9 | import org.springframework.context.annotation.Lazy; | 13 | import org.springframework.context.annotation.Lazy; |
| 10 | import org.springframework.stereotype.Service; | 14 | import org.springframework.stereotype.Service; |
| @@ -13,7 +17,7 @@ import org.springframework.validation.annotation.Validated; | @@ -13,7 +17,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 13 | import java.util.List; | 17 | import java.util.List; |
| 14 | 18 | ||
| 15 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 16 | -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_OUTSOURCE_ISSUE_DETAIL_NOT_EXISTS; | 20 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| 17 | 21 | ||
| 18 | /** | 22 | /** |
| 19 | * MES 外协发料单明细 Service 实现类 | 23 | * MES 外协发料单明细 Service 实现类 |
| @@ -28,9 +32,13 @@ public class MesWmOutsourceIssueDetailServiceImpl implements MesWmOutsourceIssue | @@ -28,9 +32,13 @@ public class MesWmOutsourceIssueDetailServiceImpl implements MesWmOutsourceIssue | ||
| 28 | private MesWmOutsourceIssueDetailMapper outsourceIssueDetailMapper; | 32 | private MesWmOutsourceIssueDetailMapper outsourceIssueDetailMapper; |
| 29 | @Resource | 33 | @Resource |
| 30 | @Lazy | 34 | @Lazy |
| 31 | - private MesWmOutsourceIssueService outsourceIssueService; | 35 | + private MesWmOutsourceIssueLineService outsourceIssueLineService; |
| 32 | @Resource | 36 | @Resource |
| 33 | private MesMdItemService itemService; | 37 | private MesMdItemService itemService; |
| 38 | + @Resource | ||
| 39 | + private MesWmWarehouseAreaService warehouseAreaService; | ||
| 40 | + @Resource | ||
| 41 | + private MesWmMaterialStockService materialStockService; | ||
| 34 | 42 | ||
| 35 | @Override | 43 | @Override |
| 36 | public Long createOutsourceIssueDetail(MesWmOutsourceIssueDetailSaveReqVO createReqVO) { | 44 | public Long createOutsourceIssueDetail(MesWmOutsourceIssueDetailSaveReqVO createReqVO) { |
| @@ -95,10 +103,26 @@ public class MesWmOutsourceIssueDetailServiceImpl implements MesWmOutsourceIssue | @@ -95,10 +103,26 @@ public class MesWmOutsourceIssueDetailServiceImpl implements MesWmOutsourceIssue | ||
| 95 | } | 103 | } |
| 96 | 104 | ||
| 97 | private void validateOutsourceIssueDetailSaveData(MesWmOutsourceIssueDetailSaveReqVO saveReqVO) { | 105 | private void validateOutsourceIssueDetailSaveData(MesWmOutsourceIssueDetailSaveReqVO saveReqVO) { |
| 98 | - // 校验关联的发料单存在 | ||
| 99 | - outsourceIssueService.getOutsourceIssue(saveReqVO.getIssueId()); | ||
| 100 | - // 校验关联的物料存在 | 106 | + // 校验父数据(行)存在 |
| 107 | + MesWmOutsourceIssueLineDO line = outsourceIssueLineService.getOutsourceIssueLine(saveReqVO.getLineId()); | ||
| 108 | + if (line == null) { | ||
| 109 | + throw exception(WM_OUTSOURCE_ISSUE_LINE_NOT_EXISTS); | ||
| 110 | + } | ||
| 111 | + if (ObjUtil.notEqual(line.getIssueId(), saveReqVO.getIssueId())) { | ||
| 112 | + throw exception(WM_OUTSOURCE_ISSUE_DETAIL_LINE_NOT_MATCH); | ||
| 113 | + } | ||
| 114 | + // 校验物料存在 | ||
| 101 | itemService.validateItemExists(saveReqVO.getItemId()); | 115 | itemService.validateItemExists(saveReqVO.getItemId()); |
| 116 | + if (ObjUtil.notEqual(line.getItemId(), saveReqVO.getItemId())) { | ||
| 117 | + throw exception(WM_OUTSOURCE_ISSUE_DETAIL_ITEM_MISMATCH); | ||
| 118 | + } | ||
| 119 | + // 校验仓库、库区、库位的关联关系 | ||
| 120 | + warehouseAreaService.validateWarehouseAreaExists( | ||
| 121 | + saveReqVO.getWarehouseId(), saveReqVO.getLocationId(), saveReqVO.getAreaId()); | ||
| 122 | + // 校验库存记录存在且物料一致 | ||
| 123 | + materialStockService.validateSelectedStock( | ||
| 124 | + saveReqVO.getMaterialStockId(), saveReqVO.getItemId(), saveReqVO.getBatchId(), null, | ||
| 125 | + saveReqVO.getWarehouseId(), saveReqVO.getLocationId(), saveReqVO.getAreaId(), saveReqVO.getQuantity()); | ||
| 102 | } | 126 | } |
| 103 | 127 | ||
| 104 | } | 128 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java
| @@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIs | @@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIs | ||
| 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO; | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO; |
| 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueDetailMapper; | 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueDetailMapper; |
| 11 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum; | 11 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum; |
| 12 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | ||
| 13 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | ||
| 12 | import jakarta.annotation.Resource; | 14 | import jakarta.annotation.Resource; |
| 13 | import org.springframework.context.annotation.Lazy; | 15 | import org.springframework.context.annotation.Lazy; |
| 14 | import org.springframework.stereotype.Service; | 16 | import org.springframework.stereotype.Service; |
| @@ -35,6 +37,10 @@ public class MesWmProductIssueDetailServiceImpl implements MesWmProductIssueDeta | @@ -35,6 +37,10 @@ public class MesWmProductIssueDetailServiceImpl implements MesWmProductIssueDeta | ||
| 35 | @Resource | 37 | @Resource |
| 36 | @Lazy | 38 | @Lazy |
| 37 | private MesWmProductIssueLineService issueLineService; | 39 | private MesWmProductIssueLineService issueLineService; |
| 40 | + @Resource | ||
| 41 | + private MesWmWarehouseAreaService warehouseAreaService; | ||
| 42 | + @Resource | ||
| 43 | + private MesWmMaterialStockService materialStockService; | ||
| 38 | 44 | ||
| 39 | @Override | 45 | @Override |
| 40 | public Long createProductIssueDetail(MesWmProductIssueDetailSaveReqVO createReqVO) { | 46 | public Long createProductIssueDetail(MesWmProductIssueDetailSaveReqVO createReqVO) { |
| @@ -116,8 +122,18 @@ public class MesWmProductIssueDetailServiceImpl implements MesWmProductIssueDeta | @@ -116,8 +122,18 @@ public class MesWmProductIssueDetailServiceImpl implements MesWmProductIssueDeta | ||
| 116 | private void validateProductIssueDetailSaveData(MesWmProductIssueDetailSaveReqVO reqVO) { | 122 | private void validateProductIssueDetailSaveData(MesWmProductIssueDetailSaveReqVO reqVO) { |
| 117 | // 校验父数据存在 | 123 | // 校验父数据存在 |
| 118 | MesWmProductIssueLineDO line = issueLineService.validateProductIssueLineExists(reqVO.getLineId()); | 124 | MesWmProductIssueLineDO line = issueLineService.validateProductIssueLineExists(reqVO.getLineId()); |
| 125 | + if (ObjUtil.notEqual(line.getIssueId(), reqVO.getIssueId())) { | ||
| 126 | + throw exception(WM_PRODUCT_ISSUE_DETAIL_LINE_NOT_MATCH); | ||
| 127 | + } | ||
| 119 | // 校验物料匹配(明细 itemId 必须与行 itemId 一致) | 128 | // 校验物料匹配(明细 itemId 必须与行 itemId 一致) |
| 120 | validateDetailItemMatch(reqVO.getItemId(), line.getItemId()); | 129 | validateDetailItemMatch(reqVO.getItemId(), line.getItemId()); |
| 130 | + // 校验仓库、库区、库位的关联关系 | ||
| 131 | + warehouseAreaService.validateWarehouseAreaExists( | ||
| 132 | + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); | ||
| 133 | + // 校验库存记录 | ||
| 134 | + materialStockService.validateSelectedStock( | ||
| 135 | + reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(), | ||
| 136 | + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity()); | ||
| 121 | } | 137 | } |
| 122 | 138 | ||
| 123 | /** | 139 | /** |
| @@ -130,4 +146,3 @@ public class MesWmProductIssueDetailServiceImpl implements MesWmProductIssueDeta | @@ -130,4 +146,3 @@ public class MesWmProductIssueDetailServiceImpl implements MesWmProductIssueDeta | ||
| 130 | } | 146 | } |
| 131 | 147 | ||
| 132 | } | 148 | } |
| 133 | - |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java
| 1 | package cn.iocoder.yudao.module.mes.service.wm.productsales; | 1 | package cn.iocoder.yudao.module.mes.service.wm.productsales; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.ObjUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 4 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailSaveReqVO; | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailSaveReqVO; |
| 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO; | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO; |
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; | ||
| 6 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper; | 8 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper; |
| 7 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | 9 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 10 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | ||
| 8 | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | 11 | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; |
| 9 | import jakarta.annotation.Resource; | 12 | import jakarta.annotation.Resource; |
| 10 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| @@ -29,17 +32,17 @@ public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDeta | @@ -29,17 +32,17 @@ public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDeta | ||
| 29 | 32 | ||
| 30 | @Resource | 33 | @Resource |
| 31 | private MesMdItemService itemService; | 34 | private MesMdItemService itemService; |
| 32 | - | 35 | + @Resource |
| 36 | + private MesWmProductSalesLineService productSalesLineService; | ||
| 37 | + @Resource | ||
| 38 | + private MesWmMaterialStockService materialStockService; | ||
| 33 | @Resource | 39 | @Resource |
| 34 | private MesWmWarehouseAreaService warehouseAreaService; | 40 | private MesWmWarehouseAreaService warehouseAreaService; |
| 35 | 41 | ||
| 36 | @Override | 42 | @Override |
| 37 | public Long createProductSalesDetail(MesWmProductSalesDetailSaveReqVO createReqVO) { | 43 | public Long createProductSalesDetail(MesWmProductSalesDetailSaveReqVO createReqVO) { |
| 38 | - // 校验物料存在 | ||
| 39 | - itemService.validateItemExists(createReqVO.getItemId()); | ||
| 40 | - // 校验库区关系 | ||
| 41 | - warehouseAreaService.validateWarehouseAreaExists( | ||
| 42 | - createReqVO.getWarehouseId(), createReqVO.getLocationId(), createReqVO.getAreaId()); | 44 | + // 校验数据 |
| 45 | + validateProductSalesDetailSaveData(createReqVO); | ||
| 43 | 46 | ||
| 44 | // 插入 | 47 | // 插入 |
| 45 | MesWmProductSalesDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductSalesDetailDO.class); | 48 | MesWmProductSalesDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductSalesDetailDO.class); |
| @@ -51,11 +54,8 @@ public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDeta | @@ -51,11 +54,8 @@ public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDeta | ||
| 51 | public void updateProductSalesDetail(MesWmProductSalesDetailSaveReqVO updateReqVO) { | 54 | public void updateProductSalesDetail(MesWmProductSalesDetailSaveReqVO updateReqVO) { |
| 52 | // 校验存在 | 55 | // 校验存在 |
| 53 | validateProductSalesDetailExists(updateReqVO.getId()); | 56 | validateProductSalesDetailExists(updateReqVO.getId()); |
| 54 | - // 校验物料存在 | ||
| 55 | - itemService.validateItemExists(updateReqVO.getItemId()); | ||
| 56 | - // 校验库区关系 | ||
| 57 | - warehouseAreaService.validateWarehouseAreaExists( | ||
| 58 | - updateReqVO.getWarehouseId(), updateReqVO.getLocationId(), updateReqVO.getAreaId()); | 57 | + // 校验数据 |
| 58 | + validateProductSalesDetailSaveData(updateReqVO); | ||
| 59 | 59 | ||
| 60 | // 更新 | 60 | // 更新 |
| 61 | MesWmProductSalesDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesDetailDO.class); | 61 | MesWmProductSalesDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesDetailDO.class); |
| @@ -103,4 +103,27 @@ public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDeta | @@ -103,4 +103,27 @@ public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDeta | ||
| 103 | return detail; | 103 | return detail; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | + private void validateProductSalesDetailSaveData(MesWmProductSalesDetailSaveReqVO reqVO) { | ||
| 107 | + // 校验父数据(行)存在 | ||
| 108 | + MesWmProductSalesLineDO line = productSalesLineService.getProductSalesLine(reqVO.getLineId()); | ||
| 109 | + if (line == null) { | ||
| 110 | + throw exception(WM_PRODUCT_SALES_LINE_NOT_EXISTS); | ||
| 111 | + } | ||
| 112 | + if (ObjUtil.notEqual(line.getSalesId(), reqVO.getSalesId())) { | ||
| 113 | + throw exception(WM_PRODUCT_SALES_DETAIL_LINE_NOT_MATCH); | ||
| 114 | + } | ||
| 115 | + // 校验物料存在 | ||
| 116 | + itemService.validateItemExists(reqVO.getItemId()); | ||
| 117 | + if (ObjUtil.notEqual(line.getItemId(), reqVO.getItemId())) { | ||
| 118 | + throw exception(WM_PRODUCT_SALES_DETAIL_ITEM_MISMATCH); | ||
| 119 | + } | ||
| 120 | + // 校验库位存在 | ||
| 121 | + warehouseAreaService.validateWarehouseAreaExists( | ||
| 122 | + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); | ||
| 123 | + // 校验库存记录存在且物料一致 | ||
| 124 | + materialStockService.validateSelectedStock( | ||
| 125 | + reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(), | ||
| 126 | + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity()); | ||
| 127 | + } | ||
| 128 | + | ||
| 106 | } | 129 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
| @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 9 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO; | 9 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO; |
| 10 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO; | 10 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO; |
| 11 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesShippingReqVO; | 11 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesShippingReqVO; |
| 12 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeDO; | ||
| 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO; | 13 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO; |
| 13 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO; | 14 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO; |
| 14 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; | 15 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; |
| @@ -16,8 +17,10 @@ import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMa | @@ -16,8 +17,10 @@ import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMa | ||
| 16 | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; | 17 | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| 17 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum; | 18 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum; |
| 18 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; | 19 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; |
| 20 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmSalesNoticeStatusEnum; | ||
| 19 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; | 21 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| 20 | import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; | 22 | import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; |
| 23 | +import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService; | ||
| 21 | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; | 24 | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| 22 | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; | 25 | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| 23 | import jakarta.annotation.Resource; | 26 | import jakarta.annotation.Resource; |
| @@ -54,6 +57,9 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService { | @@ -54,6 +57,9 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService { | ||
| 54 | private MesMdClientService clientService; | 57 | private MesMdClientService clientService; |
| 55 | 58 | ||
| 56 | @Resource | 59 | @Resource |
| 60 | + private MesWmSalesNoticeService salesNoticeService; | ||
| 61 | + | ||
| 62 | + @Resource | ||
| 57 | private MesWmTransactionService wmTransactionService; | 63 | private MesWmTransactionService wmTransactionService; |
| 58 | 64 | ||
| 59 | @Override | 65 | @Override |
| @@ -262,6 +268,16 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService { | @@ -262,6 +268,16 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService { | ||
| 262 | validateCodeUnique(id, reqVO.getCode()); | 268 | validateCodeUnique(id, reqVO.getCode()); |
| 263 | // 校验客户存在 | 269 | // 校验客户存在 |
| 264 | clientService.validateClientExists(reqVO.getClientId()); | 270 | clientService.validateClientExists(reqVO.getClientId()); |
| 271 | + // 校验发货通知单 | ||
| 272 | + if (reqVO.getNoticeId() != null) { | ||
| 273 | + MesWmSalesNoticeDO notice = salesNoticeService.validateSalesNoticeExists(reqVO.getNoticeId()); | ||
| 274 | + if (ObjUtil.notEqual(notice.getStatus(), MesWmSalesNoticeStatusEnum.APPROVED.getStatus())) { | ||
| 275 | + throw exception(WM_SALES_NOTICE_STATUS_NOT_APPROVED); | ||
| 276 | + } | ||
| 277 | + if (ObjUtil.notEqual(notice.getClientId(), reqVO.getClientId())) { | ||
| 278 | + throw exception(WM_SALES_NOTICE_CLIENT_MISMATCH); | ||
| 279 | + } | ||
| 280 | + } | ||
| 265 | } | 281 | } |
| 266 | 282 | ||
| 267 | private MesWmProductSalesDO validateProductSalesExists(Long id) { | 283 | private MesWmProductSalesDO validateProductSalesExists(Long id) { |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailServiceImpl.java
| 1 | package cn.iocoder.yudao.module.mes.service.wm.returnissue; | 1 | package cn.iocoder.yudao.module.mes.service.wm.returnissue; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.ObjUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.detail.MesWmReturnIssueDetailSaveReqVO; | 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.detail.MesWmReturnIssueDetailSaveReqVO; |
| @@ -17,8 +18,7 @@ import java.math.BigDecimal; | @@ -17,8 +18,7 @@ import java.math.BigDecimal; | ||
| 17 | import java.util.List; | 18 | import java.util.List; |
| 18 | 19 | ||
| 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 20 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 20 | -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_ISSUE_DETAIL_NOT_EXISTS; | ||
| 21 | -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_ISSUE_DETAIL_QUANTITY_EXCEED; | 21 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * MES 生产退料明细 Service 实现类 | 24 | * MES 生产退料明细 Service 实现类 |
| @@ -105,11 +105,21 @@ public class MesWmReturnIssueDetailServiceImpl implements MesWmReturnIssueDetail | @@ -105,11 +105,21 @@ public class MesWmReturnIssueDetailServiceImpl implements MesWmReturnIssueDetail | ||
| 105 | private void validateReturnIssueDetailSaveData(MesWmReturnIssueDetailSaveReqVO reqVO) { | 105 | private void validateReturnIssueDetailSaveData(MesWmReturnIssueDetailSaveReqVO reqVO) { |
| 106 | // 校验父数据存在 | 106 | // 校验父数据存在 |
| 107 | MesWmReturnIssueLineDO line = issueLineService.validateReturnIssueLineExists(reqVO.getLineId()); | 107 | MesWmReturnIssueLineDO line = issueLineService.validateReturnIssueLineExists(reqVO.getLineId()); |
| 108 | + if (ObjUtil.notEqual(line.getIssueId(), reqVO.getIssueId())) { | ||
| 109 | + throw exception(WM_RETURN_ISSUE_DETAIL_LINE_NOT_MATCH); | ||
| 110 | + } | ||
| 111 | + if (ObjUtil.notEqual(line.getItemId(), reqVO.getItemId())) { | ||
| 112 | + throw exception(WM_RETURN_ISSUE_DETAIL_ITEM_MISMATCH); | ||
| 113 | + } | ||
| 108 | // 校验仓库、库区、库位的关联关系 | 114 | // 校验仓库、库区、库位的关联关系 |
| 109 | warehouseAreaService.validateWarehouseAreaExists( | 115 | warehouseAreaService.validateWarehouseAreaExists( |
| 110 | reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); | 116 | reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); |
| 111 | // 校验库位物料/批次混放规则 | 117 | // 校验库位物料/批次混放规则 |
| 112 | materialStockService.checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId()); | 118 | materialStockService.checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId()); |
| 119 | + // 校验库存记录 | ||
| 120 | + materialStockService.validateSelectedStock( | ||
| 121 | + reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(), | ||
| 122 | + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity()); | ||
| 113 | // 校验明细总数量不超过行数量(排除自身) | 123 | // 校验明细总数量不超过行数量(排除自身) |
| 114 | validateDetailQuantityNotExceed(reqVO.getLineId(), reqVO.getQuantity(), reqVO.getId(), line); | 124 | validateDetailQuantityNotExceed(reqVO.getLineId(), reqVO.getQuantity(), reqVO.getId(), line); |
| 115 | } | 125 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorDetailServiceImpl.java
| @@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.mes.service.wm.returnvendor; | @@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.mes.service.wm.returnvendor; | ||
| 3 | import cn.hutool.core.util.ObjUtil; | 3 | import cn.hutool.core.util.ObjUtil; |
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.detail.MesWmReturnVendorDetailSaveReqVO; | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.detail.MesWmReturnVendorDetailSaveReqVO; |
| 6 | -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; | ||
| 7 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDetailDO; | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDetailDO; |
| 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO; | 7 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO; |
| 9 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorDetailMapper; | 8 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorDetailMapper; |
| 10 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | 9 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 11 | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | 10 | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| 11 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | ||
| 12 | import jakarta.annotation.Resource; | 12 | import jakarta.annotation.Resource; |
| 13 | import org.springframework.context.annotation.Lazy; | 13 | import org.springframework.context.annotation.Lazy; |
| 14 | import org.springframework.stereotype.Service; | 14 | import org.springframework.stereotype.Service; |
| @@ -32,12 +32,12 @@ public class MesWmReturnVendorDetailServiceImpl implements MesWmReturnVendorDeta | @@ -32,12 +32,12 @@ public class MesWmReturnVendorDetailServiceImpl implements MesWmReturnVendorDeta | ||
| 32 | @Resource | 32 | @Resource |
| 33 | @Lazy | 33 | @Lazy |
| 34 | private MesWmReturnVendorLineService returnVendorLineService; | 34 | private MesWmReturnVendorLineService returnVendorLineService; |
| 35 | - | ||
| 36 | @Resource | 35 | @Resource |
| 37 | private MesMdItemService itemService; | 36 | private MesMdItemService itemService; |
| 38 | - | ||
| 39 | @Resource | 37 | @Resource |
| 40 | private MesWmMaterialStockService materialStockService; | 38 | private MesWmMaterialStockService materialStockService; |
| 39 | + @Resource | ||
| 40 | + private MesWmWarehouseAreaService warehouseAreaService; | ||
| 41 | 41 | ||
| 42 | @Override | 42 | @Override |
| 43 | public Long createReturnVendorDetail(MesWmReturnVendorDetailSaveReqVO createReqVO) { | 43 | public Long createReturnVendorDetail(MesWmReturnVendorDetailSaveReqVO createReqVO) { |
| @@ -68,12 +68,18 @@ public class MesWmReturnVendorDetailServiceImpl implements MesWmReturnVendorDeta | @@ -68,12 +68,18 @@ public class MesWmReturnVendorDetailServiceImpl implements MesWmReturnVendorDeta | ||
| 68 | private void validateDetailSaveData(MesWmReturnVendorDetailSaveReqVO reqVO) { | 68 | private void validateDetailSaveData(MesWmReturnVendorDetailSaveReqVO reqVO) { |
| 69 | // 校验父数据(行)存在 | 69 | // 校验父数据(行)存在 |
| 70 | MesWmReturnVendorLineDO line = returnVendorLineService.validateReturnVendorLineExists(reqVO.getLineId()); | 70 | MesWmReturnVendorLineDO line = returnVendorLineService.validateReturnVendorLineExists(reqVO.getLineId()); |
| 71 | + if (ObjUtil.notEqual(line.getReturnId(), reqVO.getReturnId())) { | ||
| 72 | + throw exception(WM_RETURN_VENDOR_DETAIL_LINE_NOT_MATCH); | ||
| 73 | + } | ||
| 71 | // 校验物料存在 | 74 | // 校验物料存在 |
| 72 | itemService.validateItemExists(reqVO.getItemId()); | 75 | itemService.validateItemExists(reqVO.getItemId()); |
| 73 | // 校验物料与行物料一致 | 76 | // 校验物料与行物料一致 |
| 74 | validateItemConsistency(reqVO.getItemId(), line); | 77 | validateItemConsistency(reqVO.getItemId(), line); |
| 78 | + // 校验库位存在 | ||
| 79 | + warehouseAreaService.validateWarehouseAreaExists( | ||
| 80 | + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); | ||
| 75 | // 校验库存记录存在且物料一致 | 81 | // 校验库存记录存在且物料一致 |
| 76 | - validateMaterialStock(reqVO.getMaterialStockId(), line); | 82 | + validateMaterialStock(reqVO, line); |
| 77 | } | 83 | } |
| 78 | 84 | ||
| 79 | @Override | 85 | @Override |
| @@ -127,15 +133,11 @@ public class MesWmReturnVendorDetailServiceImpl implements MesWmReturnVendorDeta | @@ -127,15 +133,11 @@ public class MesWmReturnVendorDetailServiceImpl implements MesWmReturnVendorDeta | ||
| 127 | /** | 133 | /** |
| 128 | * 校验库存记录存在且物料与行物料一致 | 134 | * 校验库存记录存在且物料与行物料一致 |
| 129 | */ | 135 | */ |
| 130 | - private void validateMaterialStock(Long materialStockId, MesWmReturnVendorLineDO line) { | ||
| 131 | - if (materialStockId == null) { | ||
| 132 | - return; | ||
| 133 | - } | ||
| 134 | - MesWmMaterialStockDO stock = materialStockService.getMaterialStock(materialStockId); | ||
| 135 | - if (stock == null) { | ||
| 136 | - throw exception(WM_MATERIAL_STOCK_NOT_EXISTS); | ||
| 137 | - } | ||
| 138 | - if (ObjUtil.notEqual(stock.getItemId(), line.getItemId())) { | 136 | + private void validateMaterialStock(MesWmReturnVendorDetailSaveReqVO reqVO, MesWmReturnVendorLineDO line) { |
| 137 | + materialStockService.validateSelectedStock( | ||
| 138 | + reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(), | ||
| 139 | + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity()); | ||
| 140 | + if (ObjUtil.notEqual(line.getItemId(), reqVO.getItemId())) { | ||
| 139 | throw exception(WM_RETURN_VENDOR_DETAIL_ITEM_MISMATCH); | 141 | throw exception(WM_RETURN_VENDOR_DETAIL_ITEM_MISMATCH); |
| 140 | } | 142 | } |
| 141 | } | 143 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeService.java
| @@ -40,6 +40,14 @@ public interface MesWmSalesNoticeService { | @@ -40,6 +40,14 @@ public interface MesWmSalesNoticeService { | ||
| 40 | void deleteSalesNotice(Long id); | 40 | void deleteSalesNotice(Long id); |
| 41 | 41 | ||
| 42 | /** | 42 | /** |
| 43 | + * 校验发货通知单存在 | ||
| 44 | + * | ||
| 45 | + * @param id 编号 | ||
| 46 | + * @return 发货通知单 | ||
| 47 | + */ | ||
| 48 | + MesWmSalesNoticeDO validateSalesNoticeExists(Long id); | ||
| 49 | + | ||
| 50 | + /** | ||
| 43 | * 获得发货通知单 | 51 | * 获得发货通知单 |
| 44 | * | 52 | * |
| 45 | * @param id 编号 | 53 | * @param id 编号 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java
| @@ -111,7 +111,8 @@ public class MesWmSalesNoticeServiceImpl implements MesWmSalesNoticeService { | @@ -111,7 +111,8 @@ public class MesWmSalesNoticeServiceImpl implements MesWmSalesNoticeService { | ||
| 111 | return salesNoticeMapper.selectByIds(ids); | 111 | return salesNoticeMapper.selectByIds(ids); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | - private MesWmSalesNoticeDO validateSalesNoticeExists(Long id) { | 114 | + @Override |
| 115 | + public MesWmSalesNoticeDO validateSalesNoticeExists(Long id) { | ||
| 115 | MesWmSalesNoticeDO notice = salesNoticeMapper.selectById(id); | 116 | MesWmSalesNoticeDO notice = salesNoticeMapper.selectById(id); |
| 116 | if (notice == null) { | 117 | if (notice == null) { |
| 117 | throw exception(WM_SALES_NOTICE_NOT_EXISTS); | 118 | throw exception(WM_SALES_NOTICE_NOT_EXISTS); |