diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java index 561517f..7b4833f 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java @@ -38,10 +38,6 @@ public class MesWmItemReceiptRespVO { @ExcelProperty("到货通知单") private String noticeCode; - @Schema(description = "采购订单编号", example = "PO20260101") - @ExcelProperty("采购订单编号") - private String purchaseOrderCode; - @Schema(description = "供应商编号", example = "1") private Long vendorId; @@ -49,27 +45,6 @@ public class MesWmItemReceiptRespVO { @ExcelProperty("供应商") private String vendorName; - @Schema(description = "仓库编号", example = "1") - private Long warehouseId; - - @Schema(description = "仓库名称", example = "原料仓") - @ExcelProperty("仓库") - private String warehouseName; - - @Schema(description = "库区编号", example = "1") - private Long locationId; - - @Schema(description = "库区名称", example = "A 区") - @ExcelProperty("库区") - private String locationName; - - @Schema(description = "库位编号", example = "1") - private Long areaId; - - @Schema(description = "库位名称", example = "A-01") - @ExcelProperty("库位") - private String areaName; - @Schema(description = "入库日期") @ExcelProperty("入库日期") private LocalDateTime receiptDate; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/detail/MesWmItemReceiptDetailSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/detail/MesWmItemReceiptDetailSaveReqVO.java index a339412..e2354e0 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/detail/MesWmItemReceiptDetailSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/detail/MesWmItemReceiptDetailSaveReqVO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -27,6 +28,7 @@ public class MesWmItemReceiptDetailSaveReqVO { @Schema(description = "上架数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "300.00") @NotNull(message = "上架数量不能为空") + @DecimalMin(value = "0", inclusive = false, message = "上架数量必须大于 0") private BigDecimal quantity; @Schema(description = "批次编号", example = "1") diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineSaveReqVO.java index fd6344a..838b86b 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineSaveReqVO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -27,6 +28,7 @@ public class MesWmItemReceiptLineSaveReqVO { @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "500.00") @NotNull(message = "入库数量不能为空") + @DecimalMin(value = "0", inclusive = false, message = "入库数量必须大于 0") private BigDecimal receivedQuantity; // TODO DONE @芋艿:已添加 batchCode 字段,前端可以使用 batchCode 输入批次编码 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java index 636084d..fef7093 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java @@ -397,6 +397,7 @@ public interface ErrorCodeConstants { ErrorCode WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_NOT_ALLOWED = new ErrorCode(1_040_705_102, "入库单未关联到货通知单,不能选择到货通知单行"); ErrorCode WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_705_200, "采购入库明细不存在"); + ErrorCode WM_ITEM_RECEIPT_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_705_202, "上架明细总数量不能超过行入库数量"); // ========== MES 仓库管理-领料申请单(1-040-706-000) ========== ErrorCode WM_MATERIAL_REQUEST_NOT_EXISTS = new ErrorCode(1_040_706_000, "领料申请单不存在"); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java index a4dacb2..31debc1 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java @@ -93,6 +93,14 @@ public interface MesWmArrivalNoticeService { } /** + * 校验到货通知单存在 + * + * @param id 编号 + * @return 到货通知单 + */ + MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id); + + /** * 校验到货通知单和行存在,且行属于该通知单 * * @param noticeId 到货通知单 ID diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java index 35dccb5..f3f3e21 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java @@ -184,7 +184,8 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService } } - private MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id) { + @Override + public MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id) { MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectById(id); if (notice == null) { throw exception(WM_ARRIVAL_NOTICE_NOT_EXISTS); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java index 20a69f2..bd66b53 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java @@ -1,15 +1,19 @@ package cn.iocoder.yudao.module.mes.service.wm.itemreceipt; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper; +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -30,40 +34,53 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail private MesWmItemReceiptService itemReceiptService; @Resource + @Lazy + private MesWmItemReceiptLineService itemReceiptLineService; + + @Resource private MesWmWarehouseAreaService warehouseAreaService; + @Resource + @Lazy + private MesWmMaterialStockService materialStockService; @Override public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) { - // 校验父单据存在且为可编辑状态 + // 1. 校验数据 itemReceiptService.validateItemReceiptEditable(createReqVO.getReceiptId()); - // 校验库区关系 - warehouseAreaService.validateWarehouseAreaExists( - createReqVO.getWarehouseId(), createReqVO.getLocationId(), createReqVO.getAreaId()); - // TODO @芋艿:【后续搞】超过数量验证; - - // TODO @芋艿:【后续搞】不允许物资混放 + validateItemReceiptDetailSaveData(createReqVO); + // 2. 插入 MesWmItemReceiptDetailDO detail = BeanUtils.toBean(createReqVO, MesWmItemReceiptDetailDO.class); itemReceiptDetailMapper.insert(detail); + + // 3. 插入后校验数量是否超出 + validateDetailQuantityNotExceed(createReqVO.getLineId()); return detail.getId(); } @Override public void updateItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO updateReqVO) { - // 校验存在 + // 1.1 校验存在 MesWmItemReceiptDetailDO detail = validateItemReceiptDetailExists(updateReqVO.getId()); - // 校验父单据存在且为可编辑状态 - itemReceiptService.validateItemReceiptEditable(detail.getReceiptId()); - // 校验库区关系 - warehouseAreaService.validateWarehouseAreaExists( - updateReqVO.getWarehouseId(), updateReqVO.getLocationId(), updateReqVO.getAreaId()); - // TODO @芋艿:【后续搞】超过数量验证; - - // TODO @芋艿:【后续搞】不允许物资混放 + // 1.2 校验数据 + updateReqVO.setReceiptId(detail.getReceiptId()); + validateItemReceiptDetailSaveData(updateReqVO); - // 更新 + // 2. 更新 MesWmItemReceiptDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDetailDO.class); itemReceiptDetailMapper.updateById(updateObj); + + // 3. 更新后校验数量是否超出 + validateDetailQuantityNotExceed(detail.getLineId()); + } + + private void validateItemReceiptDetailSaveData(MesWmItemReceiptDetailSaveReqVO reqVO) { + // 校验父单据存在且为可编辑状态 + itemReceiptService.validateItemReceiptEditable(reqVO.getReceiptId()); + // 校验库区关系 + warehouseAreaService.validateWarehouseAreaExists(reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); + // 校验库位物料/批次混放规则 + materialStockService.checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId()); } @Override @@ -107,4 +124,22 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail return detail; } + /** + * 校验行下所有明细的数量之和不超过行的入库数量 + * + * @param lineId 行编号 + */ + private void validateDetailQuantityNotExceed(Long lineId) { + MesWmItemReceiptLineDO line = itemReceiptLineService.getItemReceiptLine(lineId); + if (line == null || line.getReceivedQuantity() == null) { + return; + } + List details = itemReceiptDetailMapper.selectListByLineId(lineId); + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details, + MesWmItemReceiptDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO); + if (totalDetailQty.compareTo(line.getReceivedQuantity()) > 0) { + throw exception(WM_ITEM_RECEIPT_DETAIL_QUANTITY_EXCEED); + } + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineServiceImpl.java index afc4436..8580f12 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineServiceImpl.java @@ -52,20 +52,20 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @Override public Long createItemReceiptLine(MesWmItemReceiptLineSaveReqVO createReqVO) { - // 1.1 校验父单据存在且为可编辑状态 + // 1. 校验父单据存在且为可编辑状态 MesWmItemReceiptDO receipt = itemReceiptService.validateItemReceiptEditable(createReqVO.getReceiptId()); - // 1.2 校验关联到货通知单行存在 - validateArrivalNoticeLine(receipt, createReqVO.getArrivalNoticeLineId()); + // 2. 校验数据 + validateItemReceiptLineSaveData(receipt, createReqVO); - // 2.1 创建入库单行 + // 3.1 创建入库单行 MesWmItemReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmItemReceiptLineDO.class); - // 2.2 生成或获取批次 + // 3.2 生成或获取批次 MesWmBatchDO batch = generateOrGetBatch(receipt, createReqVO); if (batch != null) { line.setBatchId(batch.getId()); line.setBatchCode(batch.getCode()); } - // 2.3 插入数据库 + // 3.3 插入数据库 itemReceiptLineMapper.insert(line); return line.getId(); } @@ -76,8 +76,8 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ MesWmItemReceiptLineDO line = validateItemReceiptLineExists(updateReqVO.getId()); // 1.2 校验父单据存在且为可编辑状态 MesWmItemReceiptDO receipt = itemReceiptService.validateItemReceiptEditable(line.getReceiptId()); - // 1.3 校验关联到货通知单行存在 - validateArrivalNoticeLine(receipt, updateReqVO.getArrivalNoticeLineId()); + // 1.3 校验数据 + validateItemReceiptLineSaveData(receipt, updateReqVO); // 2.1 更新 MesWmItemReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptLineDO.class); @@ -90,6 +90,11 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ itemReceiptLineMapper.updateById(updateObj); } + private void validateItemReceiptLineSaveData(MesWmItemReceiptDO receipt, MesWmItemReceiptLineSaveReqVO reqVO) { + // 校验关联到货通知单行 + validateArrivalNoticeLine(receipt, reqVO.getArrivalNoticeLineId()); + } + @Override @Transactional(rollbackFor = Exception.class) public void deleteItemReceiptLine(Long id) { @@ -162,6 +167,8 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ return line; } + + /** * 生成或获取批次 * diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java index 5edf17b..04062ff 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java @@ -15,6 +15,8 @@ import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapp import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum; import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; +import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService; +import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService; import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; @@ -48,14 +50,19 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @Resource @Lazy private MesWmArrivalNoticeService arrivalNoticeService; + @Resource + private MesMdVendorService vendorService; + @Resource + @Lazy + private MesQcIqcService iqcService; @Resource private MesWmTransactionService wmTransactionService; @Override public Long createItemReceipt(MesWmItemReceiptSaveReqVO createReqVO) { - // 校验编码唯一 - validateCodeUnique(null, createReqVO.getCode()); + // 校验数据 + validateItemReceiptSaveData(createReqVO); // 插入 MesWmItemReceiptDO receipt = BeanUtils.toBean(createReqVO, MesWmItemReceiptDO.class); @@ -68,14 +75,29 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { public void updateItemReceipt(MesWmItemReceiptSaveReqVO updateReqVO) { // 校验存在 + 草稿状态 validateItemReceiptExistsAndDraft(updateReqVO.getId()); - // 校验编码唯一 - validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); + // 校验数据 + validateItemReceiptSaveData(updateReqVO); // 更新 MesWmItemReceiptDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDO.class); itemReceiptMapper.updateById(updateObj); } + private void validateItemReceiptSaveData(MesWmItemReceiptSaveReqVO reqVO) { + // 校验编码唯一 + validateCodeUnique(reqVO.getId(), reqVO.getCode()); + // 校验供应商存在 + vendorService.validateVendorExists(reqVO.getVendorId()); + // 校验到货通知单存在 + if (reqVO.getNoticeId() != null) { + arrivalNoticeService.validateArrivalNoticeExists(reqVO.getNoticeId()); + } + // 校验来料检验单存在 + if (reqVO.getIqcId() != null) { + iqcService.validateIqcExists(reqVO.getIqcId()); + } + } + @Override @Transactional(rollbackFor = Exception.class) public void deleteItemReceipt(Long id) {