From 418c0ca99bf0c72eb46d523b4523a92b905fd815 Mon Sep 17 00:00:00 2001 From: HuangHuiKang Date: Tue, 16 Jun 2026 15:02:06 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E5=A4=87=E4=BB=B6=E5=87=BA=E5=BA=93?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=87=BA=E5=BA=93=E7=94=A8=E9=80=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../erp/enums/ErpStockOutUsageTypeEnum.java | 38 +++++ yudao-module-erp/yudao-module-erp-biz/pom.xml | 5 + .../admin/stock/ErpStockController.java | 148 ++++++++++++++++-- .../admin/stock/ErpStockOutController.java | 4 +- .../admin/stock/vo/out/ErpStockOutRespVO.java | 24 +++ .../stock/vo/out/ErpStockOutSaveReqVO.java | 17 ++ .../admin/stock/vo/stock/ErpStockRespVO.java | 20 +++ .../erp/dal/dataobject/stock/ErpStockDO.java | 40 +++++ .../dal/dataobject/stock/ErpStockOutDO.java | 30 ++++ .../service/stock/ErpStockOutServiceImpl.java | 40 +++++ .../service/stock/ErpStockServiceImpl.java | 63 ++++++++ .../module/mes/api/dvrepair/DvRepairApi.java | 11 ++ .../mes/api/dvrepair/dto/DvRepairRespDTO.java | 17 ++ .../ticketmanagement/TicketManagementApi.java | 11 ++ .../dto/TicketManagementRespDTO.java | 15 ++ .../mes/api/dvrepair/DvRepairApiImpl.java | 22 +++ .../TicketManagementApiImpl.java | 22 +++ .../controller/admin/user/UserController.java | 11 +- 18 files changed, 523 insertions(+), 15 deletions(-) create mode 100644 yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpStockOutUsageTypeEnum.java create mode 100644 yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApi.java create mode 100644 yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/dto/DvRepairRespDTO.java create mode 100644 yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApi.java create mode 100644 yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/dto/TicketManagementRespDTO.java create mode 100644 yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApiImpl.java create mode 100644 yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApiImpl.java diff --git a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpStockOutUsageTypeEnum.java b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpStockOutUsageTypeEnum.java new file mode 100644 index 000000000..cd3668eda --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpStockOutUsageTypeEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.erp.enums; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +@RequiredArgsConstructor +@Getter +public enum ErpStockOutUsageTypeEnum implements IntArrayValuable { + + REPAIR_RECEIVE(1, "维修领用"), + MAINTENANCE_RECEIVE(2, "保养领用"), + OTHER_OUT(3, "其他出库"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockOutUsageTypeEnum::getType).toArray(); + + private final Integer type; + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + + public static String getNameByType(Integer type) { + if (type == null) { + return null; + } + for (ErpStockOutUsageTypeEnum value : values()) { + if (value.getType().equals(type)) { + return value.getName(); + } + } + return null; + } +} diff --git a/yudao-module-erp/yudao-module-erp-biz/pom.xml b/yudao-module-erp/yudao-module-erp-biz/pom.xml index 41b280faf..7155e92e2 100644 --- a/yudao-module-erp/yudao-module-erp-biz/pom.xml +++ b/yudao-module-erp/yudao-module-erp-biz/pom.xml @@ -32,6 +32,11 @@ yudao-module-infra-api ${revision} + + cn.iocoder.boot + yudao-module-mes-api + ${revision} + diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java index 0f0f9ff68..eb47ffc3f 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java @@ -63,8 +63,8 @@ public class ErpStockController { @GetMapping("/get") @Operation(summary = "获得产品库存") @Parameters({ - @Parameter(name = "id", description = "编号", example = "1"), // 方案一:传递 id - @Parameter(name = "productId", description = "产品编号", example = "10"), // 方案二:传递 productId + warehouseId + @Parameter(name = "id", description = "编号", example = "1"), + @Parameter(name = "productId", description = "产品编号", example = "10"), @Parameter(name = "warehouseId", description = "仓库编号", example = "2") }) @PreAuthorize("@ss.hasPermission('erp:stock:query')") @@ -96,10 +96,9 @@ public class ErpStockController { @PreAuthorize("@ss.hasPermission('erp:stock:export')") @ApiAccessLog(operateType = EXPORT) public void exportStockExcel(@Valid ErpStockPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { + HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); List list = buildStockVOPageResult(stockService.getStockPage(pageReqVO)).getList(); - // 导出 Excel ExcelUtils.write(response, "产品库存.xls", "数据", ErpStockRespVO.class, list); } @@ -119,7 +118,10 @@ public class ErpStockController { .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName()) .setCategoryType(product.getCategoryType()); fillProductExtraInfo(stock, product); + fillPackagingSnapshot(stock, product); }); + stock.setPackagingRule(buildPackagingRule(stock)); + stock.setStockDisplay(buildStockDisplay(stock)); MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName())); if (stock.getAreaName() == null) { MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> stock.setAreaName(area.getAreaName())); @@ -138,10 +140,18 @@ public class ErpStockController { respVO.setProductName(product.getName()); respVO.setBarCode(product.getBarCode()); respVO.setCategoryName(product.getCategoryName()); - respVO.setUnitName(product.getUnitName()); - respVO.setCategoryType(product.getCategoryType()); + if (respVO.getUnitName() == null) { + respVO.setUnitName(product.getUnitName()); + } + if (respVO.getCategoryType() == null) { + respVO.setCategoryType(product.getCategoryType()); + } fillProductExtraInfo(respVO, product); + fillPackagingSnapshot(respVO, product); } + fillDerivedFields(respVO); + respVO.setPackagingRule(buildPackagingRule(respVO)); + respVO.setStockDisplay(buildStockDisplay(respVO)); ErpWarehouseDO warehouse = warehouseService.getWarehouse(stock.getWarehouseId()); if (warehouse != null) { respVO.setWarehouseName(warehouse.getName()); @@ -162,16 +172,64 @@ public class ErpStockController { stock.setRecentOutTime(stockRecordService.getLatestRecordTime( stock.getProductId(), stock.getWarehouseId(), stock.getAreaId(), false)); } + private void fillProductExtraInfo(ErpStockRespVO stock, ErpProductRespVO product) { - stock.setUnitId(product.getUnitId()); - stock.setPurchaseUnitId(product.getPurchaseUnitId()); - stock.setPurchaseUnitName(product.getPurchaseUnitName()); - stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity()); - stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId()); - stock.setDefaultPackagingScheme(findDefaultPackagingScheme(product)); + if (stock.getUnitId() == null) { + stock.setUnitId(product.getUnitId()); + } + if (stock.getPurchaseUnitId() == null) { + stock.setPurchaseUnitId(product.getPurchaseUnitId()); + } + if (stock.getPurchaseUnitName() == null) { + stock.setPurchaseUnitName(product.getPurchaseUnitName()); + } + if (stock.getPurchaseUnitConvertQuantity() == null) { + stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity()); + } + if (stock.getDefaultPackagingSchemeId() == null) { + stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId()); + } + if (stock.getDefaultPackagingScheme() == null) { + stock.setDefaultPackagingScheme(findDefaultPackagingScheme(product)); + } + } + + private void fillPackagingSnapshot(ErpStockRespVO stock, ErpProductRespVO product) { + if (stock.getDefaultPackagingSchemeName() != null + && stock.getPackageQuantity() != null + && stock.getPalletPackageQuantity() != null + && stock.getPalletTotalQuantity() != null) { + return; + } + ProductPackagingSchemeRespVO defaultScheme = findDefaultPackagingScheme(product); + if (defaultScheme == null) { + return; + } + if (stock.getDefaultPackagingSchemeName() == null) { + stock.setDefaultPackagingSchemeName(defaultScheme.getPackagingSchemeName()); + } + if (stock.getPackageQuantity() == null) { + stock.setPackageQuantity(defaultScheme.getPackageQuantity()); + } + if (stock.getPalletPackageQuantity() == null) { + stock.setPalletPackageQuantity(defaultScheme.getPalletPackageQuantity()); + } + if (stock.getPalletTotalQuantity() == null) { + stock.setPalletTotalQuantity(defaultScheme.getPalletTotalQuantity()); + } + } + + private void fillDerivedFields(ErpStockRespVO stock) { + if (stock.getUnitName() == null && stock.getUnitId() != null) { + // no-op: 目前库存单位名称只能从产品侧回填 + } + if (stock.getDefaultPackagingSchemeId() == null && stock.getDefaultPackagingScheme() != null) { + stock.setDefaultPackagingSchemeId(stock.getDefaultPackagingScheme().getPackagingSchemeId()); + } } + private ProductPackagingSchemeRespVO findDefaultPackagingScheme(ErpProductRespVO product) { - if (product.getDefaultPackagingSchemeId() == null || CollUtil.isEmpty(product.getPackagingSchemes())) { + if (product == null || product.getDefaultPackagingSchemeId() == null || CollUtil.isEmpty(product.getPackagingSchemes())) { return null; } return product.getPackagingSchemes().stream() @@ -179,4 +237,68 @@ public class ErpStockController { .findFirst() .orElse(null); } + + private String buildPackagingRule(ErpStockRespVO stock) { + if (stock == null) { + return null; + } + if (isProductType(stock.getCategoryType())) { + if (stock.getPackageQuantity() == null || stock.getPalletPackageQuantity() == null) { + return null; + } + return "1托=" + formatNumber(stock.getPalletPackageQuantity()) + "包 1包=" + formatNumber(stock.getPackageQuantity()) + "个"; + } + if (stock.getPurchaseUnitName() == null || stock.getPurchaseUnitConvertQuantity() == null) { + return null; + } + return "1" + stock.getPurchaseUnitName() + "=" + formatNumber(stock.getPurchaseUnitConvertQuantity()) + "个"; + } + + private String buildStockDisplay(ErpStockRespVO stock) { + if (stock == null || stock.getCount() == null) { + return null; + } + if (isProductType(stock.getCategoryType())) { + if (stock.getPalletTotalQuantity() == null || stock.getPalletTotalQuantity().compareTo(BigDecimal.ZERO) <= 0) { + return formatNumber(stock.getCount()) + stock.getUnitName(); + } + BigDecimal palletCount = stock.getCount().divideToIntegralValue(stock.getPalletTotalQuantity()); + return formatNumber(palletCount) + "托,0包,0个"; + } + if (stock.getPurchaseUnitConvertQuantity() == null || stock.getPurchaseUnitConvertQuantity().compareTo(BigDecimal.ZERO) <= 0 + || stock.getPurchaseUnitName() == null || stock.getUnitName() == null) { + return formatNumber(stock.getCount()) + stock.getUnitName(); + } + BigDecimal purchaseCount = stock.getCount().divideToIntegralValue(stock.getPurchaseUnitConvertQuantity()); + BigDecimal unitCount = stock.getCount().remainder(stock.getPurchaseUnitConvertQuantity()); + StringBuilder display = new StringBuilder(); + appendQuantity(display, purchaseCount, stock.getPurchaseUnitName(), true); + appendQuantity(display, unitCount, stock.getUnitName(), false); + return display.length() > 0 ? display.toString() : formatNumber(stock.getCount()) + stock.getUnitName(); + } + + private void appendQuantity(StringBuilder display, BigDecimal quantity, String unitName, boolean keepZero) { + if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0 || unitName == null) { + if (!keepZero) { + return; + } + if (display.length() > 0) { + display.append(","); + } + display.append("0").append(unitName); + return; + } + if (display.length() > 0) { + display.append(","); + } + display.append(formatNumber(quantity)).append(unitName); + } + + private boolean isProductType(Integer categoryType) { + return Integer.valueOf(1).equals(categoryType); + } + + private String formatNumber(BigDecimal value) { + return value == null ? "0" : value.stripTrailingZeros().toPlainString(); + } } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java index e471db81a..f7cfae1d7 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java @@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutApproveRecord import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; import cn.iocoder.yudao.module.erp.enums.ErpStockOutStatusEnum; +import cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum; import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService; import cn.iocoder.yudao.module.erp.service.mold.MoldService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; @@ -216,6 +217,7 @@ public class ErpStockOutController { List approveRecords) { ErpStockOutRespVO stockOutVO = BeanUtils.toBean(stockOut, ErpStockOutRespVO.class); stockOutVO.setStatusName(getStockOutStatusName(stockOut.getStatus())); + stockOutVO.setOutUsageTypeName(ErpStockOutUsageTypeEnum.getNameByType(stockOut.getOutUsageType())); Map userMap = adminUserApi.getUserMap(convertListByFlatMap( Collections.singletonList(stockOut), item -> Stream.of(NumberUtils.parseLong(item.getCreator()), item.getResponserId(), item.getAuditUserId()))); @@ -305,4 +307,4 @@ public class ErpStockOutController { private String getStockOutStatusName(Integer status) { return ErpStockOutStatusEnum.OUT_STOCK.getStatus().equals(status) ? "已出库" : "待出库"; } -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java index 114f8341e..1a6b29eb9 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java @@ -44,6 +44,30 @@ public class ErpStockOutRespVO { @Schema(description = "出库类型", example = "其他出库") private String outType; + @Schema(description = "出库用途", example = "1") + private Integer outUsageType; + + @Schema(description = "出库用途名称", example = "维修领用") + private String outUsageTypeName; + + @Schema(description = "维修单编号", example = "1001") + private Long repairId; + + @Schema(description = "维修单名称快照", example = "设备维修单A") + private String repairName; + + @Schema(description = "维修单设备编号", example = "2001") + private Long repairDeviceId; + + @Schema(description = "维修单设备名称快照", example = "设备A") + private String repairDeviceName; + + @Schema(description = "保养单编号", example = "3001") + private Long maintenanceId; + + @Schema(description = "保养单名称快照", example = "设备保养单A") + private String maintenanceName; + @Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("出库时间") private LocalDateTime outTime; diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVO.java index 4f4df93a1..62469c6e9 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out; import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.validation.InEnum; import lombok.Data; import javax.validation.Valid; @@ -10,6 +11,8 @@ import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; +import cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum; + @Schema(description = "管理后台 - ERP 其它出库单新增/修改 Request VO") @Data public class ErpStockOutSaveReqVO { @@ -26,6 +29,20 @@ public class ErpStockOutSaveReqVO { @Schema(description = "出库类型", example = "其他出库") private String outType; + @Schema(description = "出库用途", example = "1") + @InEnum(ErpStockOutUsageTypeEnum.class) + @NotNull(message = "出库用途不能为空") + private Integer outUsageType; + + @Schema(description = "维修单编号", example = "1001") + private Long repairId; + + @Schema(description = "维修单设备编号", example = "2001") + private Long repairDeviceId; + + @Schema(description = "保养单编号", example = "3001") + private Long maintenanceId; + @Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "出库时间不能为空") private LocalDateTime outTime; diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java index 9fde24c78..ffb58ab76 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java @@ -75,6 +75,26 @@ public class ErpStockRespVO { @Schema(description = "Default Packaging Scheme") private ProductPackagingSchemeRespVO defaultPackagingScheme; + @Schema(description = "默认包装方案名称", example = "标准包装") + private String defaultPackagingSchemeName; + + @Schema(description = "每包数量(库存单位)", example = "50") + private BigDecimal packageQuantity; + + @Schema(description = "每托包数(包)", example = "20") + private BigDecimal palletPackageQuantity; + + @Schema(description = "每托总数量(库存单位)", example = "1000") + private BigDecimal palletTotalQuantity; + + @Schema(description = "包装/换算规则", example = "1托=20包 1包=50个") + @ExcelProperty("包装/换算规则") + private String packagingRule; + + @Schema(description = "库存展示", example = "2托8包30个") + @ExcelProperty("库存展示") + private String stockDisplay; + // ========== 仓库信息 ========== @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockDO.java index 2784ee908..641aa696a 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockDO.java @@ -54,6 +54,46 @@ public class ErpStockDO extends BaseDO { * 库存数量 */ private BigDecimal count; + /** + * 库存单位编号 + */ + private Long unitId; + /** + * 库存单位名称 + */ + private String unitName; + /** + * 包装单位编号 + */ + private Long purchaseUnitId; + /** + * 包装单位名称 + */ + private String purchaseUnitName; + /** + * 包装单位与库存单位换算数量 + */ + private BigDecimal purchaseUnitConvertQuantity; + /** + * 默认包装方案编号 + */ + private Long defaultPackagingSchemeId; + /** + * 默认包装方案名称 + */ + private String defaultPackagingSchemeName; + /** + * 每包数量(库存单位) + */ + private BigDecimal packageQuantity; + /** + * 每托包数(包) + */ + private BigDecimal palletPackageQuantity; + /** + * 每托总数量(库存单位) + */ + private BigDecimal palletTotalQuantity; /** * 产品分类编号 */ diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutDO.java index 51753f700..cfb03caba 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutDO.java @@ -48,6 +48,36 @@ public class ErpStockOutDO extends BaseDO { private Long responserId; //@Schema(description = "出库类型", example = "随便") private String outType; + /** + * 出库用途 + * + * 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum} + */ + private Integer outUsageType; + /** + * 维修单名称快照 + */ + private String repairName; + /** + * 维修单编号 + */ + private Long repairId; + /** + * 维修单设备编号 + */ + private Long repairDeviceId; + /** + * 维修单设备名称快照 + */ + private String repairDeviceName; + /** + * 保养单编号 + */ + private Long maintenanceId; + /** + * 保养单名称快照 + */ + private String maintenanceName; /** * 出库时间 */ diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java index d9d7999c0..e836824d2 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java @@ -26,8 +26,13 @@ import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutItemMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutMapper; import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; +import cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockOutApproveActionEnum; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum; +import cn.iocoder.yudao.module.mes.api.dvrepair.DvRepairApi; +import cn.iocoder.yudao.module.mes.api.dvrepair.dto.DvRepairRespDTO; +import cn.iocoder.yudao.module.mes.api.ticketmanagement.TicketManagementApi; +import cn.iocoder.yudao.module.mes.api.ticketmanagement.dto.TicketManagementRespDTO; import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService; import cn.iocoder.yudao.module.erp.service.mold.MoldService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; @@ -96,6 +101,10 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { private ConfigApi configApi; @Resource private PermissionApi permissionApi; + @Resource + private DvRepairApi dvRepairApi; + @Resource + private TicketManagementApi ticketManagementApi; @Override @Transactional(rollbackFor = Exception.class) @@ -123,6 +132,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { .setStatus(status) .setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add)) .setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); + fillUsageSnapshot(stockOut, createReqVO.getOutUsageType(), createReqVO.getRepairId(), + createReqVO.getRepairDeviceId(), createReqVO.getMaintenanceId()); stockOutMapper.insert(stockOut); stockOutItems.forEach(item -> item.setOutId(stockOut.getId())); stockOutItemMapper.insertBatch(stockOutItems); @@ -165,6 +176,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { .setNeedAudit(needAudit) .setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add)) .setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); + fillUsageSnapshot(updateObj, updateReqVO.getOutUsageType(), updateReqVO.getRepairId(), + updateReqVO.getRepairDeviceId(), updateReqVO.getMaintenanceId()); stockOutMapper.updateById(updateObj); updateStockOutItemList(updateReqVO.getId(), stockOutItems); } @@ -394,6 +407,33 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { return !AUDIT_CONFIG_DISABLE_VALUE.equals(configApi.getConfigValueByCategoryAndKey(AUDIT_CONFIG_CATEGORY, AUDIT_CONFIG_KEY)); } + private void fillUsageSnapshot(ErpStockOutDO stockOut, Integer outUsageType, Long repairId, + Long repairDeviceId, Long maintenanceId) { + stockOut.setOutUsageType(outUsageType); + stockOut.setRepairId(null); + stockOut.setRepairName(null); + stockOut.setRepairDeviceId(null); + stockOut.setRepairDeviceName(null); + stockOut.setMaintenanceId(null); + stockOut.setMaintenanceName(null); + + if (ErpStockOutUsageTypeEnum.REPAIR_RECEIVE.getType().equals(outUsageType) && repairId != null) { + DvRepairRespDTO repair = dvRepairApi.getDvRepair(repairId); + if (repair != null) { + stockOut.setRepairId(repair.getId()); + stockOut.setRepairName(repair.getRepairName()); + stockOut.setRepairDeviceId(repairDeviceId != null ? repairDeviceId : repair.getMachineryId()); + stockOut.setRepairDeviceName(repair.getMachineryName()); + } + } else if (ErpStockOutUsageTypeEnum.MAINTENANCE_RECEIVE.getType().equals(outUsageType) && maintenanceId != null) { + TicketManagementRespDTO maintenance = ticketManagementApi.getTicketManagement(maintenanceId); + if (maintenance != null) { + stockOut.setMaintenanceId(maintenance.getId()); + stockOut.setMaintenanceName(maintenance.getPlanNo()); + } + } + } + private void createApproveRecord(Long stockOutId, ErpStockOutApproveActionEnum action, Integer fromStatus, Integer toStatus, Long targetUserId, String remark) { stockOutApproveRecordMapper.insert(ErpStockOutApproveRecordDO.builder() diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java index c3ef910ef..25d6a680a 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.erp.service.stock; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper; @@ -90,12 +91,14 @@ public class ErpStockServiceImpl implements ErpStockService { String areaName, BigDecimal count) { ErpProductRespVO product = productService.getProduct(productId); Integer categoryType = product != null ? product.getCategoryType() : null; + ProductPackagingSchemeRespVO defaultPackagingScheme = product != null ? findDefaultPackagingScheme(product) : null; // 1.1 查询当前库存 ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseIdAndAreaId(productId, warehouseId, areaId); if (stock == null) { stock = new ErpStockDO().setProductId(productId).setWarehouseId(warehouseId).setAreaId(areaId) .setAreaName(areaName).setCount(BigDecimal.ZERO).setCategoryType(categoryType); stock.setCategoryId(categoryId); + fillStockSnapshot(stock, product, defaultPackagingScheme); stockMapper.insert(stock); } else if (stock.getCategoryType() == null) { stock.setCategoryType(categoryType); @@ -105,6 +108,10 @@ public class ErpStockServiceImpl implements ErpStockService { stock.setAreaName(areaName); stockMapper.updateById(new ErpStockDO().setId(stock.getId()).setAreaName(areaName)); } + if (product != null && isStockSnapshotMissing(stock)) { + fillStockSnapshot(stock, product, defaultPackagingScheme); + stockMapper.updateById(buildStockSnapshotUpdate(stock)); + } // 1.2 校验库存是否充足 if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) { throw exception(STOCK_COUNT_NEGATIVE, productService.getProduct(productId).getName(), @@ -123,4 +130,60 @@ public class ErpStockServiceImpl implements ErpStockService { return stock.getCount().add(count); } + private void fillStockSnapshot(ErpStockDO stock, ErpProductRespVO product, + ProductPackagingSchemeRespVO defaultPackagingScheme) { + if (product == null) { + return; + } + stock.setUnitId(product.getUnitId()); + stock.setUnitName(product.getUnitName()); + stock.setPurchaseUnitId(product.getPurchaseUnitId()); + stock.setPurchaseUnitName(product.getPurchaseUnitName()); + stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity()); + if (defaultPackagingScheme != null) { + stock.setDefaultPackagingSchemeId(defaultPackagingScheme.getPackagingSchemeId()); + stock.setDefaultPackagingSchemeName(defaultPackagingScheme.getPackagingSchemeName()); + stock.setPackageQuantity(defaultPackagingScheme.getPackageQuantity()); + stock.setPalletPackageQuantity(defaultPackagingScheme.getPalletPackageQuantity()); + stock.setPalletTotalQuantity(defaultPackagingScheme.getPalletTotalQuantity()); + } + } + + private ProductPackagingSchemeRespVO findDefaultPackagingScheme(ErpProductRespVO product) { + if (product.getDefaultPackagingSchemeId() == null || product.getPackagingSchemes() == null) { + return null; + } + return product.getPackagingSchemes().stream() + .filter(item -> product.getDefaultPackagingSchemeId().equals(item.getPackagingSchemeId())) + .findFirst() + .orElse(null); + } + + private boolean isStockSnapshotMissing(ErpStockDO stock) { + return stock.getUnitId() == null + || stock.getUnitName() == null + || stock.getPurchaseUnitId() == null + || stock.getPurchaseUnitName() == null + || stock.getPurchaseUnitConvertQuantity() == null + || stock.getDefaultPackagingSchemeId() == null + || stock.getDefaultPackagingSchemeName() == null + || stock.getPackageQuantity() == null + || stock.getPalletPackageQuantity() == null + || stock.getPalletTotalQuantity() == null; + } + + private ErpStockDO buildStockSnapshotUpdate(ErpStockDO stock) { + return new ErpStockDO().setId(stock.getId()) + .setUnitId(stock.getUnitId()) + .setUnitName(stock.getUnitName()) + .setPurchaseUnitId(stock.getPurchaseUnitId()) + .setPurchaseUnitName(stock.getPurchaseUnitName()) + .setPurchaseUnitConvertQuantity(stock.getPurchaseUnitConvertQuantity()) + .setDefaultPackagingSchemeId(stock.getDefaultPackagingSchemeId()) + .setDefaultPackagingSchemeName(stock.getDefaultPackagingSchemeName()) + .setPackageQuantity(stock.getPackageQuantity()) + .setPalletPackageQuantity(stock.getPalletPackageQuantity()) + .setPalletTotalQuantity(stock.getPalletTotalQuantity()); + } + } diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApi.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApi.java new file mode 100644 index 000000000..16b6e7ccc --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApi.java @@ -0,0 +1,11 @@ +package cn.iocoder.yudao.module.mes.api.dvrepair; + +import cn.iocoder.yudao.module.mes.api.dvrepair.dto.DvRepairRespDTO; + +/** + * 设备维修 API + */ +public interface DvRepairApi { + + DvRepairRespDTO getDvRepair(Long id); +} diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/dto/DvRepairRespDTO.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/dto/DvRepairRespDTO.java new file mode 100644 index 000000000..3773d04a3 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/dto/DvRepairRespDTO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.mes.api.dvrepair.dto; + +import lombok.Data; + +/** + * 设备维修响应 DTO + */ +@Data +public class DvRepairRespDTO { + + private Long id; + private String repairCode; + private String repairName; + private Long machineryId; + private String machineryCode; + private String machineryName; +} diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApi.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApi.java new file mode 100644 index 000000000..a7e08be90 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApi.java @@ -0,0 +1,11 @@ +package cn.iocoder.yudao.module.mes.api.ticketmanagement; + +import cn.iocoder.yudao.module.mes.api.ticketmanagement.dto.TicketManagementRespDTO; + +/** + * 保养单 API + */ +public interface TicketManagementApi { + + TicketManagementRespDTO getTicketManagement(Long id); +} diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/dto/TicketManagementRespDTO.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/dto/TicketManagementRespDTO.java new file mode 100644 index 000000000..10ab0a114 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/dto/TicketManagementRespDTO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.mes.api.ticketmanagement.dto; + +import lombok.Data; + +/** + * 保养单响应 DTO + */ +@Data +public class TicketManagementRespDTO { + + private Long id; + private String planNo; + private String deviceName; + private String configName; +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApiImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApiImpl.java new file mode 100644 index 000000000..582c06a23 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/dvrepair/DvRepairApiImpl.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.mes.api.dvrepair; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.api.dvrepair.dto.DvRepairRespDTO; +import cn.iocoder.yudao.module.mes.dal.dataobject.dvrepair.DvRepairDO; +import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairMapper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +public class DvRepairApiImpl implements DvRepairApi { + + @Resource + private DvRepairMapper dvRepairMapper; + + @Override + public DvRepairRespDTO getDvRepair(Long id) { + DvRepairDO repair = dvRepairMapper.selectById(id); + return BeanUtils.toBean(repair, DvRepairRespDTO.class); + } +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApiImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApiImpl.java new file mode 100644 index 000000000..c677d3220 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/api/ticketmanagement/TicketManagementApiImpl.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.mes.api.ticketmanagement; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.api.ticketmanagement.dto.TicketManagementRespDTO; +import cn.iocoder.yudao.module.mes.dal.dataobject.ticketmanagement.TicketManagementDO; +import cn.iocoder.yudao.module.mes.dal.mysql.ticketmanagement.TicketManagementMapper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +public class TicketManagementApiImpl implements TicketManagementApi { + + @Resource + private TicketManagementMapper ticketManagementMapper; + + @Override + public TicketManagementRespDTO getTicketManagement(Long id) { + TicketManagementDO ticketManagement = ticketManagementMapper.selectById(id); + return BeanUtils.toBean(ticketManagement, TicketManagementRespDTO.class); + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index 3f7dc6127..1fd74ade4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -105,8 +105,17 @@ public class UserController { @GetMapping({"/list-all-simple", "/simple-list"}) @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项") - public CommonResult> getSimpleUserList() { + public CommonResult> getSimpleUserList(@RequestParam(value = "username", required = false) String username, + @RequestParam(value = "nickname", required = false) String nickname) { List list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus()); + if (username != null && !username.isEmpty()) { + list = list.stream().filter(user -> user.getUsername() != null && user.getUsername().contains(username)) + .collect(java.util.stream.Collectors.toList()); + } + if (nickname != null && !nickname.isEmpty()) { + list = list.stream().filter(user -> user.getNickname() != null && user.getNickname().contains(nickname)) + .collect(java.util.stream.Collectors.toList()); + } // 拼接数据 Map deptMap = deptService.getDeptMap( convertList(list, AdminUserDO::getDeptId));