diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptController.java new file mode 100644 index 0000000..9b4106e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptController.java @@ -0,0 +1,177 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDO; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; +import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; +import cn.iocoder.yudao.module.mes.service.wm.productrecpt.MesWmProductRecptService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - MES 产品收货单") +@RestController +@RequestMapping("/mes/wm/product-recpt") +@Validated +public class MesWmProductRecptController { + + @Resource + private MesWmProductRecptService productRecptService; + + @Resource + private MesProWorkOrderService workOrderService; + + @Resource + private MesMdItemService itemService; + + @Resource + private MesMdUnitMeasureService unitMeasureService; + + @PostMapping("/create") + @Operation(summary = "创建产品收货单") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:create')") + public CommonResult createProductRecpt(@Valid @RequestBody MesWmProductRecptSaveReqVO createReqVO) { + return success(productRecptService.createProductRecpt(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "修改产品收货单") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:update')") + public CommonResult updateProductRecpt(@Valid @RequestBody MesWmProductRecptSaveReqVO updateReqVO) { + productRecptService.updateProductRecpt(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除产品收货单") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:delete')") + public CommonResult deleteProductRecpt(@RequestParam("id") Long id) { + productRecptService.deleteProductRecpt(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得产品收货单") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:query')") + public CommonResult getProductRecpt(@RequestParam("id") Long id) { + MesWmProductRecptDO recpt = productRecptService.getProductRecpt(id); + if (recpt == null) { + return success(null); + } + return success(buildRespVOList(Collections.singletonList(recpt)).get(0)); + } + + @GetMapping("/page") + @Operation(summary = "获得产品收货单分页") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:query')") + public CommonResult> getProductRecptPage( + @Valid MesWmProductRecptPageReqVO pageReqVO) { + PageResult pageResult = productRecptService.getProductRecptPage(pageReqVO); + return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal())); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出产品收货单 Excel") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportProductRecptExcel(@Valid MesWmProductRecptPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + PageResult pageResult = productRecptService.getProductRecptPage(pageReqVO); + ExcelUtils.write(response, "产品收货单.xls", "数据", MesWmProductRecptRespVO.class, + buildRespVOList(pageResult.getList())); + } + + @PutMapping("/submit") + @Operation(summary = "提交产品收货单") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:update')") + public CommonResult submitProductRecpt(@RequestParam("id") Long id) { + productRecptService.submitProductRecpt(id); + return success(true); + } + + @PutMapping("/stock") + @Operation(summary = "执行上架") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:update')") + public CommonResult stockProductRecpt(@RequestParam("id") Long id) { + productRecptService.stockProductRecpt(id); + return success(true); + } + + @PutMapping("/execute") + @Operation(summary = "执行入库") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:execute')") + public CommonResult executeProductRecpt(@RequestParam("id") Long id) { + productRecptService.executeProductRecpt(id); + return success(true); + } + + @PutMapping("/cancel") + @Operation(summary = "取消产品收货单") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:update')") + public CommonResult cancelProductRecpt(@RequestParam("id") Long id) { + productRecptService.cancelProductRecpt(id); + return success(true); + } + + // ==================== 拼接 VO ==================== + + private List buildRespVOList(List list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); + } + // 1. 获得关联数据 + Map workOrderMap = workOrderService.getWorkOrderMap( + convertSet(list, MesWmProductRecptDO::getWorkOrderId)); + Map itemMap = itemService.getItemMap( + convertSet(list, MesWmProductRecptDO::getItemId)); + Map unitMeasureMap = unitMeasureService.getUnitMeasureMap( + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); + // 2. 构建结果 + return BeanUtils.toBean(list, MesWmProductRecptRespVO.class, vo -> { + MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(), + workOrder -> vo.setWorkOrderCode(workOrder.getCode())); + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); + }); + }); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptDetailController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptDetailController.java new file mode 100644 index 0000000..82fc027 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptDetailController.java @@ -0,0 +1,140 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.detail.MesWmProductRecptDetailRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.detail.MesWmProductRecptDetailSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDetailDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; +import cn.iocoder.yudao.module.mes.service.wm.productrecpt.MesWmProductRecptDetailService; +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - MES 产品收货单明细") +@RestController +@RequestMapping("/mes/wm/product-recpt-detail") +@Validated +public class MesWmProductRecptDetailController { + + @Resource + private MesWmProductRecptDetailService productRecptDetailService; + + @Resource + private MesMdItemService itemService; + + @Resource + private MesMdUnitMeasureService unitMeasureService; + + @Resource + private MesWmWarehouseService warehouseService; + + @Resource + private MesWmWarehouseLocationService locationService; + + @Resource + private MesWmWarehouseAreaService areaService; + + @PostMapping("/create") + @Operation(summary = "创建产品收货单明细") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:create')") + public CommonResult createProductRecptDetail(@Valid @RequestBody MesWmProductRecptDetailSaveReqVO createReqVO) { + return success(productRecptDetailService.createProductRecptDetail(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "修改产品收货单明细") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:update')") + public CommonResult updateProductRecptDetail(@Valid @RequestBody MesWmProductRecptDetailSaveReqVO updateReqVO) { + productRecptDetailService.updateProductRecptDetail(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除产品收货单明细") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:delete')") + public CommonResult deleteProductRecptDetail(@RequestParam("id") Long id) { + productRecptDetailService.deleteProductRecptDetail(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得产品收货单明细") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:query')") + public CommonResult getProductRecptDetail(@RequestParam("id") Long id) { + MesWmProductRecptDetailDO detail = productRecptDetailService.getProductRecptDetail(id); + if (detail == null) { + return success(null); + } + return success(buildRespVOList(Collections.singletonList(detail)).get(0)); + } + + @GetMapping("/list-by-line") + @Operation(summary = "获得产品收货单明细列表(按行编号)") + @Parameter(name = "lineId", description = "行编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:query')") + public CommonResult> getProductRecptDetailListByLineId( + @RequestParam("lineId") Long lineId) { + List list = productRecptDetailService.getProductRecptDetailListByLineId(lineId); + return success(buildRespVOList(list)); + } + + // ==================== 拼接 VO ==================== + + private List buildRespVOList(List list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); + } + // 1. 获得关联数据 + Map itemMap = itemService.getItemMap( + convertSet(list, MesWmProductRecptDetailDO::getItemId)); + Map unitMeasureMap = unitMeasureService.getUnitMeasureMap( + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); + Map warehouseMap = warehouseService.getWarehouseMap( + convertSet(list, MesWmProductRecptDetailDO::getWarehouseId)); + Map locationMap = locationService.getWarehouseLocationMap( + convertSet(list, MesWmProductRecptDetailDO::getLocationId)); + Map areaMap = areaService.getWarehouseAreaMap( + convertSet(list, MesWmProductRecptDetailDO::getAreaId)); + // 2. 构建结果 + return BeanUtils.toBean(list, MesWmProductRecptDetailRespVO.class, vo -> { + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); + }); + MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(), + warehouse -> vo.setWarehouseName(warehouse.getName())); + MapUtils.findAndThen(locationMap, vo.getLocationId(), + location -> vo.setLocationName(location.getName())); + MapUtils.findAndThen(areaMap, vo.getAreaId(), + area -> vo.setAreaName(area.getName())); + }); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptLineController.java new file mode 100644 index 0000000..4348dd8 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/MesWmProductRecptLineController.java @@ -0,0 +1,114 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLinePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLineRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLineSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptLineDO; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; +import cn.iocoder.yudao.module.mes.service.wm.productrecpt.MesWmProductRecptLineService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - MES 产品收货单行") +@RestController +@RequestMapping("/mes/wm/product-recpt-line") +@Validated +public class MesWmProductRecptLineController { + + @Resource + private MesWmProductRecptLineService productRecptLineService; + + @Resource + private MesMdItemService itemService; + + @Resource + private MesMdUnitMeasureService unitMeasureService; + + @PostMapping("/create") + @Operation(summary = "创建产品收货单行") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:create')") + public CommonResult createProductRecptLine(@Valid @RequestBody MesWmProductRecptLineSaveReqVO createReqVO) { + return success(productRecptLineService.createProductRecptLine(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "修改产品收货单行") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:update')") + public CommonResult updateProductRecptLine(@Valid @RequestBody MesWmProductRecptLineSaveReqVO updateReqVO) { + productRecptLineService.updateProductRecptLine(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除产品收货单行") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:delete')") + public CommonResult deleteProductRecptLine(@RequestParam("id") Long id) { + productRecptLineService.deleteProductRecptLine(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得产品收货单行") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:query')") + public CommonResult getProductRecptLine(@RequestParam("id") Long id) { + MesWmProductRecptLineDO line = productRecptLineService.getProductRecptLine(id); + if (line == null) { + return success(null); + } + return success(buildRespVOList(Collections.singletonList(line)).get(0)); + } + + @GetMapping("/page") + @Operation(summary = "获得产品收货单行分页") + @PreAuthorize("@ss.hasPermission('mes:wm-product-recpt:query')") + public CommonResult> getProductRecptLinePage( + @Valid MesWmProductRecptLinePageReqVO pageReqVO) { + PageResult pageResult = productRecptLineService.getProductRecptLinePage(pageReqVO); + return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal())); + } + + // ==================== 拼接 VO ==================== + + private List buildRespVOList(List list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); + } + // 1. 获得关联数据 + Map itemMap = itemService.getItemMap( + convertSet(list, MesWmProductRecptLineDO::getItemId)); + Map unitMeasureMap = unitMeasureService.getUnitMeasureMap( + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); + // 2. 构建结果 + return BeanUtils.toBean(list, MesWmProductRecptLineRespVO.class, vo -> { + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); + }); + }); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptPageReqVO.java new file mode 100644 index 0000000..d063260 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptPageReqVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - MES 产品收货单分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MesWmProductRecptPageReqVO extends PageParam { + + @Schema(description = "收货单编码", example = "PR202603010001") + private String code; + + @Schema(description = "收货单名称", example = "产品收货单-工单001") + private String name; + + @Schema(description = "生产工单编号", example = "1") + private Long workOrderId; + + @Schema(description = "产品物料编号", example = "1") + private Long itemId; + + @Schema(description = "状态", example = "0") + private Integer status; + + @Schema(description = "收货日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] receiptDate; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptRespVO.java new file mode 100644 index 0000000..bf31195 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptRespVO.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 产品收货单 Response VO") +@Data +@ExcelIgnoreUnannotated +public class MesWmProductRecptRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "收货单编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "PR202603010001") + @ExcelProperty("收货单编码") + private String code; + + @Schema(description = "收货单名称", example = "产品收货单-工单001") + @ExcelProperty("收货单名称") + private String name; + + @Schema(description = "生产工单编号", example = "1") + private Long workOrderId; + + @Schema(description = "生产工单编码", example = "WO202603010001") + @ExcelProperty("生产工单") + private String workOrderCode; + + @Schema(description = "产品物料编号", example = "1") + private Long itemId; + + @Schema(description = "产品物料编码", example = "P001") + @ExcelProperty("产品物料编码") + private String itemCode; + + @Schema(description = "产品物料名称", example = "成品A") + @ExcelProperty("产品物料名称") + private String itemName; + + @Schema(description = "规格型号", example = "标准型") + @ExcelProperty("规格型号") + private String specification; + + @Schema(description = "计量单位名称", example = "件") + @ExcelProperty("计量单位") + private String unitMeasureName; + + @Schema(description = "收货日期") + @ExcelProperty("收货日期") + private LocalDateTime receiptDate; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @ExcelProperty("状态") + private Integer status; + + @Schema(description = "备注", example = "备注") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptSaveReqVO.java new file mode 100644 index 0000000..d96f64f --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/MesWmProductRecptSaveReqVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 产品收货单新增/修改 Request VO") +@Data +public class MesWmProductRecptSaveReqVO { + + @Schema(description = "编号", example = "1024") + private Long id; + + @Schema(description = "收货单编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "PR202603010001") + @NotEmpty(message = "收货单编码不能为空") + private String code; + + @Schema(description = "收货单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品收货单-工单001") + @NotEmpty(message = "收货单名称不能为空") + private String name; + + @Schema(description = "生产工单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + // TODO @AI:workOrderId 必须要非必传 + @NotNull(message = "生产工单不能为空") + private Long workOrderId; + + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "产品物料不能为空") + // TODO @AI:workOrderId 必须要非必传 + private Long itemId; + + @Schema(description = "收货日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "收货日期不能为空") + private LocalDateTime receiptDate; + + @Schema(description = "备注", example = "备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/detail/MesWmProductRecptDetailRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/detail/MesWmProductRecptDetailRespVO.java new file mode 100644 index 0000000..64b0d5c --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/detail/MesWmProductRecptDetailRespVO.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.detail; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 产品收货单明细 Response VO") +@Data +public class MesWmProductRecptDetailRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "收货单行编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long lineId; + + @Schema(description = "收货单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long recptId; + + @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long itemId; + + @Schema(description = "物料编码", example = "P001") + private String itemCode; + + @Schema(description = "物料名称", example = "成品A") + private String itemName; + + @Schema(description = "规格型号", example = "标准型") + private String specification; + + @Schema(description = "计量单位名称", example = "件") + private String unitMeasureName; + + @Schema(description = "上架数量", example = "100.00") + private BigDecimal quantity; + + @Schema(description = "批次编号", example = "1") + private Long batchId; + + @Schema(description = "仓库编号", example = "1") + private Long warehouseId; + + @Schema(description = "仓库名称", example = "成品仓") + private String warehouseName; + + @Schema(description = "库区编号", example = "1") + private Long locationId; + + @Schema(description = "库区名称", example = "A区") + private String locationName; + + @Schema(description = "库位编号", example = "1") + private Long areaId; + + @Schema(description = "库位名称", example = "A-01") + private String areaName; + + @Schema(description = "备注", example = "备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/detail/MesWmProductRecptDetailSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/detail/MesWmProductRecptDetailSaveReqVO.java new file mode 100644 index 0000000..33be93f --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/detail/MesWmProductRecptDetailSaveReqVO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.detail; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - MES 产品收货单明细新增/修改 Request VO") +@Data +public class MesWmProductRecptDetailSaveReqVO { + + @Schema(description = "编号", example = "1024") + private Long id; + + @Schema(description = "收货单行编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "收货单行编号不能为空") + private Long lineId; + + @Schema(description = "收货单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "收货单编号不能为空") + private Long recptId; + + @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "物料编号不能为空") + private Long itemId; + + @Schema(description = "上架数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") + @NotNull(message = "上架数量不能为空") + private BigDecimal quantity; + + @Schema(description = "批次编号", example = "1") + private Long batchId; + + @Schema(description = "仓库编号", example = "1") + private Long warehouseId; + + @Schema(description = "库区编号", example = "1") + private Long locationId; + + @Schema(description = "库位编号", example = "1") + private Long areaId; + + @Schema(description = "备注", example = "备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLinePageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLinePageReqVO.java new file mode 100644 index 0000000..c5311e6 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLinePageReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - MES 产品收货单行分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MesWmProductRecptLinePageReqVO extends PageParam { + + @Schema(description = "收货单编号", example = "1") + private Long recptId; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLineRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLineRespVO.java new file mode 100644 index 0000000..1f06a4e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLineRespVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 产品收货单行 Response VO") +@Data +public class MesWmProductRecptLineRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "收货单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long recptId; + + @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long itemId; + + @Schema(description = "物料编码", example = "P001") + private String itemCode; + + @Schema(description = "物料名称", example = "成品A") + private String itemName; + + @Schema(description = "规格型号", example = "标准型") + private String specification; + + @Schema(description = "计量单位名称", example = "件") + private String unitMeasureName; + + @Schema(description = "收货数量", example = "100.00") + private BigDecimal quantity; + + @Schema(description = "批次编号", example = "1") + private Long batchId; + + @Schema(description = "批次号", example = "BATCH20260301001") + private String batchCode; + + @Schema(description = "备注", example = "备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLineSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLineSaveReqVO.java new file mode 100644 index 0000000..7806589 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productrecpt/vo/line/MesWmProductRecptLineSaveReqVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - MES 产品收货单行新增/修改 Request VO") +@Data +public class MesWmProductRecptLineSaveReqVO { + + @Schema(description = "编号", example = "1024") + private Long id; + + @Schema(description = "收货单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "收货单编号不能为空") + private Long recptId; + + @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "物料编号不能为空") + private Long itemId; + + @Schema(description = "收货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") + @NotNull(message = "收货数量不能为空") + private BigDecimal quantity; + + @Schema(description = "批次编号", example = "1") + private Long batchId; + + @Schema(description = "批次号", example = "BATCH20260301001") + private String batchCode; + + @Schema(description = "备注", example = "备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptDO.java new file mode 100644 index 0000000..95a3eb4 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptDO.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; +import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductRecptStatusEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.time.LocalDateTime; + +/** + * MES 产品收货(入库)单 DO + */ +@TableName("mes_wm_product_recpt") +@KeySequence("mes_wm_product_recpt_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesWmProductRecptDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 收货单编码 + */ + private String code; + /** + * 收货单名称 + */ + private String name; + /** + * 生产工单编号 + * + * 关联 {@link MesProWorkOrderDO#getId()} + */ + private Long workOrderId; + /** + * 产品物料编号 + * + * 关联 {@link MesMdItemDO#getId()} + */ + private Long itemId; + /** + * 收货日期 + */ + private LocalDateTime receiptDate; + /** + * 状态 + * + * 枚举 {@link MesWmProductRecptStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptDetailDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptDetailDO.java new file mode 100644 index 0000000..b8272ff --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptDetailDO.java @@ -0,0 +1,84 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * MES 产品收货(入库)单明细 DO + */ +@TableName("mes_wm_product_recpt_detail") +@KeySequence("mes_wm_product_recpt_detail_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesWmProductRecptDetailDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 收货单行编号 + * + * 关联 {@link MesWmProductRecptLineDO#getId()} + */ + private Long lineId; + /** + * 收货单编号 + * + * 关联 {@link MesWmProductRecptDO#getId()} + */ + private Long recptId; + /** + * 物料编号 + * + * 关联 {@link MesMdItemDO#getId()} + */ + private Long itemId; + /** + * 上架数量 + */ + private BigDecimal quantity; + /** + * 批次编号 + * + * TODO DONE @芋艿:保留。待 mes_wm_batch 模块迁移后补充 @link 关联 + */ + private Long batchId; + /** + * 仓库编号 + * + * 关联 {@link MesWmWarehouseDO#getId()} + */ + private Long warehouseId; + /** + * 库区编号 + * + * 关联 {@link MesWmWarehouseLocationDO#getId()} + */ + private Long locationId; + /** + * 库位编号 + * + * 关联 {@link MesWmWarehouseAreaDO#getId()} + */ + private Long areaId; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptLineDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptLineDO.java new file mode 100644 index 0000000..e3eaaf1 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productrecpt/MesWmProductRecptLineDO.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * MES 产品收货(入库)单行 DO + */ +@TableName("mes_wm_product_recpt_line") +@KeySequence("mes_wm_product_recpt_line_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesWmProductRecptLineDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 收货单编号 + * + * 关联 {@link MesWmProductRecptDO#getId()} + */ + private Long recptId; + /** + * 物料编号 + * + * 关联 {@link MesMdItemDO#getId()} + */ + private Long itemId; + /** + * 收货数量 + */ + private BigDecimal quantity; + /** + * 批次编号 + * + * TODO DONE @芋艿:保留。待 mes_wm_batch 模块迁移后补充 @link 关联 + */ + private Long batchId; + /** + * 批次号 + */ + private String batchCode; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptDetailMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptDetailMapper.java new file mode 100644 index 0000000..c4084bb --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptDetailMapper.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productrecpt; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDetailDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 产品收货单明细 Mapper + */ +@Mapper +public interface MesWmProductRecptDetailMapper extends BaseMapperX { + + default List selectListByRecptId(Long recptId) { + return selectList(MesWmProductRecptDetailDO::getRecptId, recptId); + } + + default List selectListByLineId(Long lineId) { + return selectList(MesWmProductRecptDetailDO::getLineId, lineId); + } + + default void deleteByRecptId(Long recptId) { + delete(MesWmProductRecptDetailDO::getRecptId, recptId); + } + + default void deleteByLineId(Long lineId) { + delete(MesWmProductRecptDetailDO::getLineId, lineId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptLineMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptLineMapper.java new file mode 100644 index 0000000..dad722a --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptLineMapper.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productrecpt; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLinePageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptLineDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 产品收货单行 Mapper + */ +@Mapper +public interface MesWmProductRecptLineMapper extends BaseMapperX { + + default PageResult selectPage(MesWmProductRecptLinePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(MesWmProductRecptLineDO::getRecptId, reqVO.getRecptId()) + .orderByDesc(MesWmProductRecptLineDO::getId)); + } + + default List selectListByRecptId(Long recptId) { + return selectList(MesWmProductRecptLineDO::getRecptId, recptId); + } + + default void deleteByRecptId(Long recptId) { + delete(MesWmProductRecptLineDO::getRecptId, recptId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptMapper.java new file mode 100644 index 0000000..c3f560b --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productrecpt/MesWmProductRecptMapper.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productrecpt; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptPageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * MES 产品收货单 Mapper + */ +@Mapper +public interface MesWmProductRecptMapper extends BaseMapperX { + + default PageResult selectPage(MesWmProductRecptPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(MesWmProductRecptDO::getCode, reqVO.getCode()) + .likeIfPresent(MesWmProductRecptDO::getName, reqVO.getName()) + .eqIfPresent(MesWmProductRecptDO::getWorkOrderId, reqVO.getWorkOrderId()) + .eqIfPresent(MesWmProductRecptDO::getItemId, reqVO.getItemId()) + .eqIfPresent(MesWmProductRecptDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(MesWmProductRecptDO::getReceiptDate, reqVO.getReceiptDate()) + .orderByDesc(MesWmProductRecptDO::getId)); + } + + default MesWmProductRecptDO selectByCode(String code) { + return selectOne(MesWmProductRecptDO::getCode, code); + } + +} 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 66b183d..1d4e1c2 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 @@ -402,4 +402,15 @@ public interface ErrorCodeConstants { ErrorCode WM_RETURN_VENDOR_LINE_NOT_EXISTS = new ErrorCode(1_040_711_100, "供应商退货单行不存在"); ErrorCode WM_RETURN_VENDOR_DETAIL_NOT_EXISTS = new ErrorCode(1_040_711_200, "供应商退货单明细不存在"); + // ========== MES 仓库管理-产品收货单(1-040-712-000) ========== + ErrorCode WM_PRODUCT_RECPT_NOT_EXISTS = new ErrorCode(1_040_712_000, "产品收货单不存在"); + ErrorCode WM_PRODUCT_RECPT_CODE_DUPLICATE = new ErrorCode(1_040_712_001, "产品收货单编码已存在"); + ErrorCode WM_PRODUCT_RECPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_712_002, "只有草稿或待上架状态才允许此操作"); + ErrorCode WM_PRODUCT_RECPT_NO_LINE = new ErrorCode(1_040_712_003, "至少需要一条行项目"); + ErrorCode WM_PRODUCT_RECPT_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_712_004, "明细上架总数与行收货数量不匹配"); + ErrorCode WM_PRODUCT_RECPT_STATUS_ERROR = new ErrorCode(1_040_712_005, "收货单状态不正确"); + ErrorCode WM_PRODUCT_RECPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_712_006, "已完成或已取消的收货单不允许取消"); + ErrorCode WM_PRODUCT_RECPT_LINE_NOT_EXISTS = new ErrorCode(1_040_712_100, "产品收货单行不存在"); + ErrorCode WM_PRODUCT_RECPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_712_200, "产品收货明细不存在"); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductRecptStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductRecptStatusEnum.java new file mode 100644 index 0000000..3f67d43 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductRecptStatusEnum.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.mes.enums.wm; + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * MES 产品收货单状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum MesWmProductRecptStatusEnum implements ArrayValuable { + + // TODO @AI:对应的方法;参考别的 MesWmProductionIssueStatusEnum + /** + * 草稿 + */ + PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), + /** + * 待上架 + */ + APPROVING(MesOrderStatusConstants.APPROVING, "待上架"), + /** + * 待执行入库 + */ + APPROVED(MesOrderStatusConstants.APPROVED, "待执行入库"), + /** + * 已完成 + */ + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"), + /** + * 已取消 + */ + CANCELED(MesOrderStatusConstants.CANCELLED, "已取消"); + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductRecptStatusEnum::getStatus).toArray(Integer[]::new); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public Integer[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptDetailService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptDetailService.java new file mode 100644 index 0000000..2c59240 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptDetailService.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.mes.service.wm.productrecpt; + +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.detail.MesWmProductRecptDetailSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDetailDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * MES 产品收货单明细 Service 接口 + */ +public interface MesWmProductRecptDetailService { + + /** + * 创建产品收货单明细 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createProductRecptDetail(@Valid MesWmProductRecptDetailSaveReqVO createReqVO); + + /** + * 修改产品收货单明细 + * + * @param updateReqVO 修改信息 + */ + void updateProductRecptDetail(@Valid MesWmProductRecptDetailSaveReqVO updateReqVO); + + /** + * 删除产品收货单明细 + * + * @param id 编号 + */ + void deleteProductRecptDetail(Long id); + + /** + * 获得产品收货单明细 + * + * @param id 编号 + * @return 产品收货单明细 + */ + MesWmProductRecptDetailDO getProductRecptDetail(Long id); + + /** + * 按收货单编号获得明细列表 + * + * @param recptId 收货单编号 + * @return 明细列表 + */ + List getProductRecptDetailListByRecptId(Long recptId); + + /** + * 按收货单行编号获得明细列表 + * + * @param lineId 行编号 + * @return 明细列表 + */ + List getProductRecptDetailListByLineId(Long lineId); + + /** + * 按收货单行编号批量删除明细 + * + * @param lineId 行编号 + */ + void deleteProductRecptDetailByLineId(Long lineId); + + /** + * 按收货单编号批量删除明细 + * + * @param recptId 收货单编号 + */ + void deleteProductRecptDetailByRecptId(Long recptId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptDetailServiceImpl.java new file mode 100644 index 0000000..27bac05 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptDetailServiceImpl.java @@ -0,0 +1,104 @@ +package cn.iocoder.yudao.module.mes.service.wm.productrecpt; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.detail.MesWmProductRecptDetailSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDetailDO; +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productrecpt.MesWmProductRecptDetailMapper; +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.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * MES 产品收货单明细 Service 实现类 + */ +@Service +@Validated +public class MesWmProductRecptDetailServiceImpl implements MesWmProductRecptDetailService { + + @Resource + private MesWmProductRecptDetailMapper productRecptDetailMapper; + + @Resource + @Lazy + private MesWmProductRecptService productRecptService; + + @Resource + private MesWmWarehouseAreaService warehouseAreaService; + + @Override + public Long createProductRecptDetail(MesWmProductRecptDetailSaveReqVO createReqVO) { + // 校验父单据存在且为可编辑状态 + productRecptService.validateProductRecptEditable(createReqVO.getRecptId()); + // 校验库区关系 + warehouseAreaService.validateWarehouseAreaExists( + createReqVO.getWarehouseId(), createReqVO.getLocationId(), createReqVO.getAreaId()); + + MesWmProductRecptDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductRecptDetailDO.class); + productRecptDetailMapper.insert(detail); + return detail.getId(); + } + + @Override + public void updateProductRecptDetail(MesWmProductRecptDetailSaveReqVO updateReqVO) { + // 校验存在 + MesWmProductRecptDetailDO detail = validateProductRecptDetailExists(updateReqVO.getId()); + // 校验父单据存在且为可编辑状态 + productRecptService.validateProductRecptEditable(detail.getRecptId()); + // 校验库区关系 + warehouseAreaService.validateWarehouseAreaExists( + updateReqVO.getWarehouseId(), updateReqVO.getLocationId(), updateReqVO.getAreaId()); + + // 更新 + MesWmProductRecptDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductRecptDetailDO.class); + productRecptDetailMapper.updateById(updateObj); + } + + @Override + public void deleteProductRecptDetail(Long id) { + // 校验存在 + validateProductRecptDetailExists(id); + // 删除 + productRecptDetailMapper.deleteById(id); + } + + @Override + public MesWmProductRecptDetailDO getProductRecptDetail(Long id) { + return productRecptDetailMapper.selectById(id); + } + + @Override + public List getProductRecptDetailListByRecptId(Long recptId) { + return productRecptDetailMapper.selectListByRecptId(recptId); + } + + @Override + public List getProductRecptDetailListByLineId(Long lineId) { + return productRecptDetailMapper.selectListByLineId(lineId); + } + + @Override + public void deleteProductRecptDetailByLineId(Long lineId) { + productRecptDetailMapper.deleteByLineId(lineId); + } + + @Override + public void deleteProductRecptDetailByRecptId(Long recptId) { + productRecptDetailMapper.deleteByRecptId(recptId); + } + + private MesWmProductRecptDetailDO validateProductRecptDetailExists(Long id) { + MesWmProductRecptDetailDO detail = productRecptDetailMapper.selectById(id); + if (detail == null) { + throw exception(WM_PRODUCT_RECPT_DETAIL_NOT_EXISTS); + } + return detail; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptLineService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptLineService.java new file mode 100644 index 0000000..2590cd7 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptLineService.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.mes.service.wm.productrecpt; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLinePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLineSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptLineDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * MES 产品收货单行 Service 接口 + */ +public interface MesWmProductRecptLineService { + + /** + * 创建产品收货单行 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createProductRecptLine(@Valid MesWmProductRecptLineSaveReqVO createReqVO); + + /** + * 修改产品收货单行 + * + * @param updateReqVO 修改信息 + */ + void updateProductRecptLine(@Valid MesWmProductRecptLineSaveReqVO updateReqVO); + + /** + * 删除产品收货单行(级联删除明细) + * + * @param id 编号 + */ + void deleteProductRecptLine(Long id); + + /** + * 获得产品收货单行 + * + * @param id 编号 + * @return 产品收货单行 + */ + MesWmProductRecptLineDO getProductRecptLine(Long id); + + /** + * 获得产品收货单行分页 + * + * @param pageReqVO 分页参数 + * @return 产品收货单行分页 + */ + PageResult getProductRecptLinePage(MesWmProductRecptLinePageReqVO pageReqVO); + + /** + * 按收货单编号获得行列表 + * + * @param recptId 收货单编号 + * @return 行列表 + */ + List getProductRecptLineListByRecptId(Long recptId); + + /** + * 按收货单编号批量删除行 + * + * @param recptId 收货单编号 + */ + void deleteProductRecptLineByRecptId(Long recptId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptLineServiceImpl.java new file mode 100644 index 0000000..98ccb7e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptLineServiceImpl.java @@ -0,0 +1,100 @@ +package cn.iocoder.yudao.module.mes.service.wm.productrecpt; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLinePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.line.MesWmProductRecptLineSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptLineDO; +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productrecpt.MesWmProductRecptLineMapper; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCT_RECPT_LINE_NOT_EXISTS; + +/** + * MES 产品收货单行 Service 实现类 + */ +@Service +@Validated +public class MesWmProductRecptLineServiceImpl implements MesWmProductRecptLineService { + + @Resource + private MesWmProductRecptLineMapper productRecptLineMapper; + + @Resource + @Lazy + private MesWmProductRecptService productRecptService; + + @Resource + private MesWmProductRecptDetailService productRecptDetailService; + + @Override + public Long createProductRecptLine(MesWmProductRecptLineSaveReqVO createReqVO) { + // 校验父单据存在且为可编辑状态 + productRecptService.validateProductRecptEditable(createReqVO.getRecptId()); + + // 新增 + MesWmProductRecptLineDO line = BeanUtils.toBean(createReqVO, MesWmProductRecptLineDO.class); + productRecptLineMapper.insert(line); + return line.getId(); + } + + @Override + public void updateProductRecptLine(MesWmProductRecptLineSaveReqVO updateReqVO) { + // 校验存在 + MesWmProductRecptLineDO line = validateProductRecptLineExists(updateReqVO.getId()); + // 校验父单据存在且为可编辑状态 + productRecptService.validateProductRecptEditable(line.getRecptId()); + + // 更新 + MesWmProductRecptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductRecptLineDO.class); + productRecptLineMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteProductRecptLine(Long id) { + // 校验存在 + validateProductRecptLineExists(id); + + // 级联删除明细 + productRecptDetailService.deleteProductRecptDetailByLineId(id); + // 删除 + productRecptLineMapper.deleteById(id); + } + + @Override + public MesWmProductRecptLineDO getProductRecptLine(Long id) { + return productRecptLineMapper.selectById(id); + } + + @Override + public PageResult getProductRecptLinePage(MesWmProductRecptLinePageReqVO pageReqVO) { + return productRecptLineMapper.selectPage(pageReqVO); + } + + @Override + public List getProductRecptLineListByRecptId(Long recptId) { + return productRecptLineMapper.selectListByRecptId(recptId); + } + + @Override + public void deleteProductRecptLineByRecptId(Long recptId) { + productRecptLineMapper.deleteByRecptId(recptId); + } + + private MesWmProductRecptLineDO validateProductRecptLineExists(Long id) { + MesWmProductRecptLineDO line = productRecptLineMapper.selectById(id); + if (line == null) { + throw exception(WM_PRODUCT_RECPT_LINE_NOT_EXISTS); + } + return line; + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptService.java new file mode 100644 index 0000000..db42864 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptService.java @@ -0,0 +1,88 @@ +package cn.iocoder.yudao.module.mes.service.wm.productrecpt; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDO; +import jakarta.validation.Valid; + +/** + * MES 产品收货单 Service 接口 + */ +public interface MesWmProductRecptService { + + /** + * 创建产品收货单 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createProductRecpt(@Valid MesWmProductRecptSaveReqVO createReqVO); + + /** + * 修改产品收货单 + * + * @param updateReqVO 修改信息 + */ + void updateProductRecpt(@Valid MesWmProductRecptSaveReqVO updateReqVO); + + /** + * 删除产品收货单(级联删除行+明细) + * + * @param id 编号 + */ + void deleteProductRecpt(Long id); + + /** + * 获得产品收货单 + * + * @param id 编号 + * @return 产品收货单 + */ + MesWmProductRecptDO getProductRecpt(Long id); + + /** + * 获得产品收货单分页 + * + * @param pageReqVO 分页参数 + * @return 产品收货单分页 + */ + PageResult getProductRecptPage(MesWmProductRecptPageReqVO pageReqVO); + + /** + * 提交产品收货单(草稿 → 待上架) + * + * @param id 编号 + */ + void submitProductRecpt(Long id); + + /** + * 执行上架(待上架 → 待入库) + * + * @param id 编号 + */ + void stockProductRecpt(Long id); + + /** + * 执行入库(待入库 → 已完成),更新库存台账 + * + * @param id 编号 + */ + void executeProductRecpt(Long id); + + /** + * 取消产品收货单(任意非已完成/已取消状态 → 已取消) + * + * @param id 编号 + */ + void cancelProductRecpt(Long id); + + /** + * 校验产品收货单存在且处于可编辑状态(草稿或待上架) + * + * @param id 编号 + * @return 产品收货单 + */ + MesWmProductRecptDO validateProductRecptEditable(Long id); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptServiceImpl.java new file mode 100644 index 0000000..f37400f --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productrecpt/MesWmProductRecptServiceImpl.java @@ -0,0 +1,211 @@ +package cn.iocoder.yudao.module.mes.service.wm.productrecpt; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.wm.productrecpt.vo.MesWmProductRecptSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptDetailDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productrecpt.MesWmProductRecptLineDO; +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productrecpt.MesWmProductRecptMapper; +import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductRecptStatusEnum; +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.math.BigDecimal; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * MES 产品收货单 Service 实现类 + */ +@Service +@Validated +public class MesWmProductRecptServiceImpl implements MesWmProductRecptService { + + @Resource + private MesWmProductRecptMapper productRecptMapper; + + @Resource + private MesWmProductRecptLineService productRecptLineService; + + @Resource + private MesWmProductRecptDetailService productRecptDetailService; + + @Resource + private MesWmMaterialStockService materialStockService; + + @Override + public Long createProductRecpt(MesWmProductRecptSaveReqVO createReqVO) { + // 校验编码唯一 + validateCodeUnique(null, createReqVO.getCode()); + + // 插入 + MesWmProductRecptDO recpt = BeanUtils.toBean(createReqVO, MesWmProductRecptDO.class); + recpt.setStatus(MesWmProductRecptStatusEnum.PREPARE.getStatus()); + productRecptMapper.insert(recpt); + return recpt.getId(); + } + + @Override + public void updateProductRecpt(MesWmProductRecptSaveReqVO updateReqVO) { + // 校验存在 + 草稿状态 + validateProductRecptExistsAndDraft(updateReqVO.getId()); + // 校验编码唯一 + validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); + + // 更新 + MesWmProductRecptDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductRecptDO.class); + productRecptMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteProductRecpt(Long id) { + // 校验存在 + 草稿状态 + validateProductRecptExistsAndDraft(id); + + // 级联删除明细和行 + productRecptDetailService.deleteProductRecptDetailByRecptId(id); + productRecptLineService.deleteProductRecptLineByRecptId(id); + // 删除 + productRecptMapper.deleteById(id); + } + + @Override + public MesWmProductRecptDO getProductRecpt(Long id) { + return productRecptMapper.selectById(id); + } + + @Override + public PageResult getProductRecptPage(MesWmProductRecptPageReqVO pageReqVO) { + return productRecptMapper.selectPage(pageReqVO); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void submitProductRecpt(Long id) { + // 校验存在 + 草稿状态 + validateProductRecptExistsAndDraft(id); + // 校验至少有一条行 + List lines = productRecptLineService.getProductRecptLineListByRecptId(id); + if (CollUtil.isEmpty(lines)) { + throw exception(WM_PRODUCT_RECPT_NO_LINE); + } + + // 提交(草稿 → 待上架) + productRecptMapper.updateById(new MesWmProductRecptDO() + .setId(id).setStatus(MesWmProductRecptStatusEnum.APPROVING.getStatus())); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void stockProductRecpt(Long id) { + // 校验存在 + MesWmProductRecptDO recpt = validateProductRecptExists(id); + if (ObjUtil.notEqual(MesWmProductRecptStatusEnum.APPROVING.getStatus(), recpt.getStatus())) { + throw exception(WM_PRODUCT_RECPT_STATUS_ERROR); + } + // 校验每行明细数量之和是否等于行收货数量 + List lines = productRecptLineService.getProductRecptLineListByRecptId(id); + for (MesWmProductRecptLineDO line : lines) { + List details = productRecptDetailService.getProductRecptDetailListByLineId(line.getId()); + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details, + MesWmProductRecptDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO); + if (line.getQuantity() != null && totalDetailQty.compareTo(line.getQuantity()) != 0) { + throw exception(WM_PRODUCT_RECPT_DETAIL_QUANTITY_MISMATCH); + } + } + + // 执行上架(待上架 → 待入库) + productRecptMapper.updateById(new MesWmProductRecptDO() + .setId(id).setStatus(MesWmProductRecptStatusEnum.APPROVED.getStatus())); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void executeProductRecpt(Long id) { + // 校验存在 + MesWmProductRecptDO recpt = validateProductRecptExists(id); + if (ObjUtil.notEqual(MesWmProductRecptStatusEnum.APPROVED.getStatus(), recpt.getStatus())) { + throw exception(WM_PRODUCT_RECPT_STATUS_ERROR); + } + + // 遍历所有明细,更新库存台账 + List details = productRecptDetailService.getProductRecptDetailListByRecptId(id); + for (MesWmProductRecptDetailDO detail : details) { + materialStockService.increaseStock( + detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(), + detail.getBatchId(), detail.getQuantity(), null, null, null); + } + + // 更新收货单状态 + productRecptMapper.updateById(new MesWmProductRecptDO() + .setId(id).setStatus(MesWmProductRecptStatusEnum.FINISHED.getStatus())); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void cancelProductRecpt(Long id) { + // 校验存在 + MesWmProductRecptDO recpt = validateProductRecptExists(id); + // 已完成和已取消不允许取消 + if (ObjectUtils.equalsAny(recpt.getStatus(), + MesWmProductRecptStatusEnum.FINISHED.getStatus(), + MesWmProductRecptStatusEnum.CANCELED.getStatus())) { + throw exception(WM_PRODUCT_RECPT_CANCEL_NOT_ALLOWED); + } + // 取消 + productRecptMapper.updateById(new MesWmProductRecptDO() + .setId(id).setStatus(MesWmProductRecptStatusEnum.CANCELED.getStatus())); + } + + @Override + public MesWmProductRecptDO validateProductRecptEditable(Long id) { + MesWmProductRecptDO recpt = validateProductRecptExists(id); + if (ObjUtil.notEqual(recpt.getStatus(), MesWmProductRecptStatusEnum.PREPARE.getStatus()) + && ObjUtil.notEqual(recpt.getStatus(), MesWmProductRecptStatusEnum.APPROVING.getStatus())) { + throw exception(WM_PRODUCT_RECPT_STATUS_NOT_PREPARE); + } + return recpt; + } + + private MesWmProductRecptDO validateProductRecptExists(Long id) { + MesWmProductRecptDO recpt = productRecptMapper.selectById(id); + if (recpt == null) { + throw exception(WM_PRODUCT_RECPT_NOT_EXISTS); + } + return recpt; + } + + /** + * 校验产品收货单存在且为草稿状态 + */ + private MesWmProductRecptDO validateProductRecptExistsAndDraft(Long id) { + MesWmProductRecptDO recpt = validateProductRecptExists(id); + if (ObjUtil.notEqual(MesWmProductRecptStatusEnum.PREPARE.getStatus(), recpt.getStatus())) { + throw exception(WM_PRODUCT_RECPT_STATUS_NOT_PREPARE); + } + return recpt; + } + + private void validateCodeUnique(Long id, String code) { + MesWmProductRecptDO recpt = productRecptMapper.selectByCode(code); + if (recpt == null) { + return; + } + if (ObjUtil.notEqual(id, recpt.getId())) { + throw exception(WM_PRODUCT_RECPT_CODE_DUPLICATE); + } + } + +} diff --git a/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/detail/index.ts b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/detail/index.ts new file mode 100644 index 0000000..d7e29fb --- /dev/null +++ b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/detail/index.ts @@ -0,0 +1,51 @@ +import request from '@/config/axios' + +// MES 产品收货单明细 VO +export interface WmProductRecptDetailVO { + id: number + lineId: number + recptId: number + itemId: number + itemCode: string + itemName: string + specification: string + unitMeasureName: string + quantity: number + batchId: number + warehouseId: number + warehouseName: string + locationId: number + locationName: string + areaId: number + areaName: string + remark: string + createTime: string +} + +// MES 产品收货单明细 API +export const WmProductRecptDetailApi = { + // 查询产品收货单明细详情 + getProductRecptDetail: async (id: number) => { + return await request.get({ url: '/mes/wm/product-recpt-detail/get?id=' + id }) + }, + + // 查询产品收货单明细列表(按行编号) + getProductRecptDetailListByLineId: async (lineId: number) => { + return await request.get({ url: '/mes/wm/product-recpt-detail/list-by-line?lineId=' + lineId }) + }, + + // 新增产品收货单明细 + createProductRecptDetail: async (data: WmProductRecptDetailVO) => { + return await request.post({ url: '/mes/wm/product-recpt-detail/create', data }) + }, + + // 修改产品收货单明细 + updateProductRecptDetail: async (data: WmProductRecptDetailVO) => { + return await request.put({ url: '/mes/wm/product-recpt-detail/update', data }) + }, + + // 删除产品收货单明细 + deleteProductRecptDetail: async (id: number) => { + return await request.delete({ url: '/mes/wm/product-recpt-detail/delete?id=' + id }) + } +} diff --git a/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/index.ts b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/index.ts new file mode 100644 index 0000000..6602c20 --- /dev/null +++ b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/index.ts @@ -0,0 +1,72 @@ +import request from '@/config/axios' + +// MES 产品收货单 VO +export interface WmProductRecptVO { + id: number + code: string + name: string + workOrderId: number + workOrderCode: string + itemId: number + itemCode: string + itemName: string + specification: string + unitMeasureName: string + receiptDate: string + status: number + remark: string + createTime: string +} + +// MES 产品收货单 API +export const WmProductRecptApi = { + // 查询产品收货单分页 + getProductRecptPage: async (params: any) => { + return await request.get({ url: '/mes/wm/product-recpt/page', params }) + }, + + // 查询产品收货单详情 + getProductRecpt: async (id: number) => { + return await request.get({ url: '/mes/wm/product-recpt/get?id=' + id }) + }, + + // 新增产品收货单 + createProductRecpt: async (data: WmProductRecptVO) => { + return await request.post({ url: '/mes/wm/product-recpt/create', data }) + }, + + // 修改产品收货单 + updateProductRecpt: async (data: WmProductRecptVO) => { + return await request.put({ url: '/mes/wm/product-recpt/update', data }) + }, + + // 删除产品收货单 + deleteProductRecpt: async (id: number) => { + return await request.delete({ url: '/mes/wm/product-recpt/delete?id=' + id }) + }, + + // 提交产品收货单 + submitProductRecpt: async (id: number) => { + return await request.put({ url: '/mes/wm/product-recpt/submit?id=' + id }) + }, + + // 执行上架 + stockProductRecpt: async (id: number) => { + return await request.put({ url: '/mes/wm/product-recpt/stock?id=' + id }) + }, + + // 执行入库 + executeProductRecpt: async (id: number) => { + return await request.put({ url: '/mes/wm/product-recpt/execute?id=' + id }) + }, + + // 取消产品收货单 + cancelProductRecpt: async (id: number) => { + return await request.put({ url: '/mes/wm/product-recpt/cancel?id=' + id }) + }, + + // 导出产品收货单 Excel + exportProductRecpt: async (params: any) => { + return await request.download({ url: '/mes/wm/product-recpt/export-excel', params }) + } +} diff --git a/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/line/index.ts b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/line/index.ts new file mode 100644 index 0000000..c879e98 --- /dev/null +++ b/yudao-ui/yudao-ui-admin-vue3/src/api/mes/wm/productrecpt/line/index.ts @@ -0,0 +1,45 @@ +import request from '@/config/axios' + +// MES 产品收货单行 VO +export interface WmProductRecptLineVO { + id: number + recptId: number + itemId: number + itemCode: string + itemName: string + specification: string + unitMeasureName: string + receivedQuantity: number + batchId: number + batchCode: string + remark: string + createTime: string +} + +// MES 产品收货单行 API +export const WmProductRecptLineApi = { + // 查询产品收货单行分页 + getProductRecptLinePage: async (params: any) => { + return await request.get({ url: '/mes/wm/product-recpt-line/page', params }) + }, + + // 查询产品收货单行详情 + getProductRecptLine: async (id: number) => { + return await request.get({ url: '/mes/wm/product-recpt-line/get?id=' + id }) + }, + + // 新增产品收货单行 + createProductRecptLine: async (data: WmProductRecptLineVO) => { + return await request.post({ url: '/mes/wm/product-recpt-line/create', data }) + }, + + // 修改产品收货单行 + updateProductRecptLine: async (data: WmProductRecptLineVO) => { + return await request.put({ url: '/mes/wm/product-recpt-line/update', data }) + }, + + // 删除产品收货单行 + deleteProductRecptLine: async (id: number) => { + return await request.delete({ url: '/mes/wm/product-recpt-line/delete?id=' + id }) + } +}