yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/decision/DecisionForecastController.java
@@ -2,6 +2,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastHistorySaveReqVO; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastReqVO; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastRespVO; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastWorkOrderCreateReqVO; @@ -39,6 +40,13 @@ return success(forecastService.getForecastList(reqVO.getForecastCode(), beginTime, endTime)); } @PostMapping("/history") @Operation(summary = "æ°å¢åå²é¢æµæ°æ®") @PreAuthorize("@ss.hasPermission('bi:decision:kpi:update')") public CommonResult<Long> createForecastHistory(@Valid @RequestBody DecisionForecastHistorySaveReqVO reqVO) { return success(forecastService.createForecastHistory(reqVO)); } @PostMapping("/generate") @Operation(summary = "çæé¢æµï¼å ä½ï¼") @PreAuthorize("@ss.hasPermission('bi:decision:kpi:query')") yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/decision/vo/DecisionForecastHistorySaveReqVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,50 @@ package cn.iocoder.yudao.module.bi.controller.admin.decision.vo; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; @Schema(description = "管çåå° - è´è·é¢æµå岿°æ®æ°å¢ Request VO") @Data public class DecisionForecastHistorySaveReqVO { @Schema(description = "颿µç¼ç ", requiredMode = Schema.RequiredMode.REQUIRED) @Size(max = 64) @jakarta.validation.constraints.NotBlank private String forecastCode; @Schema(description = "颿µåç§°", requiredMode = Schema.RequiredMode.REQUIRED) @Size(max = 128) @jakarta.validation.constraints.NotBlank private String forecastName; @Schema(description = "颿µæ¶é´ç¹", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull private LocalDateTime pointTime; @Schema(description = "颿µå¼", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull @DecimalMin(value = "0", inclusive = true) private BigDecimal forecastValue; @Schema(description = "å®é å¼") @DecimalMin(value = "0", inclusive = true) private BigDecimal actualValue; @Schema(description = "维度") @Size(max = 32) private String dimension; @Schema(description = "维度å¼") @Size(max = 128) private String dimensionValue; @Schema(description = "夿³¨") @Size(max = 500) private String remark; } yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/dal/mysql/decision/BiForecastDataMapper.java
@@ -19,4 +19,14 @@ .between(BiForecastDataDO::getPointTime, beginTime, endTime) .orderByAsc(BiForecastDataDO::getPointTime)); } /** * æ¥è¯¢æå®é¢æµç¼ç ä¸æè¿ n æ¡é¢æµæ°æ®ï¼ææ¶é´ååºï¼ç¨äºç§»å¨å¹³åï¼ */ default List<BiForecastDataDO> selectRecentByCode(String forecastCode, int limit) { return selectList(new LambdaQueryWrapper<BiForecastDataDO>() .eq(BiForecastDataDO::getForecastCode, forecastCode) .orderByDesc(BiForecastDataDO::getPointTime) .last("LIMIT " + limit)); } } yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/enums/ErrorCodeConstants.java
@@ -39,5 +39,6 @@ // ========== å³çæ¯æ - è´è·é¢æµ 1_080_221 ~ 1_080_240 ========== ErrorCode BI_FORECAST_NOT_EXISTS = new ErrorCode(1_080_221, "è´è·é¢æµæ°æ®ä¸åå¨"); ErrorCode BI_FORECAST_NO_HISTORY = new ErrorCode(1_080_222, "è¯¥é¢æµç¼ç 䏿æ å岿°æ®ï¼æ æ³çæé¢æµ"); } yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiForecastService.java
@@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bi.service.decision; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastHistorySaveReqVO; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastWorkOrderCreateReqVO; import cn.iocoder.yudao.module.bi.dal.dataobject.decision.BiForecastDataDO; @@ -17,6 +18,8 @@ void generateForecast(String forecastCode, LocalDateTime pointTime); Long createForecastHistory(DecisionForecastHistorySaveReqVO reqVO); /** * è´è·é¢æµèå¨å建ç产工åï¼è¿ç»´/åçµ/æ£ä¿®ç±»ï¼ * yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiForecastServiceImpl.java
@@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.bi.service.decision; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastHistorySaveReqVO; import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastWorkOrderCreateReqVO; import cn.iocoder.yudao.module.bi.dal.dataobject.decision.BiForecastDataDO; import cn.iocoder.yudao.module.bi.dal.mysql.decision.BiForecastDataMapper; @@ -12,10 +14,12 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.bi.enums.ErrorCodeConstants.BI_FORECAST_NO_HISTORY; import static cn.iocoder.yudao.module.bi.enums.ErrorCodeConstants.BI_FORECAST_NOT_EXISTS; /** @@ -44,21 +48,51 @@ return forecastDataMapper.selectListByCodeAndTimeRange(forecastCode, beginTime, endTime); } /** * ç§»å¨å¹³åçªå£å¤§å° */ private static final int SMA_WINDOW = 12; @Override public Long createForecastHistory(DecisionForecastHistorySaveReqVO reqVO) { BiForecastDataDO data = BiForecastDataDO.builder() .forecastCode(reqVO.getForecastCode()) .forecastName(reqVO.getForecastName()) .pointTime(reqVO.getPointTime()) .forecastValue(reqVO.getForecastValue()) .actualValue(reqVO.getActualValue()) .dimension(reqVO.getDimension()) .dimensionValue(reqVO.getDimensionValue()) .remark(reqVO.getRemark()) .modelVersion("manual-history") .build(); forecastDataMapper.insert(data); return data.getId(); } @Override public void generateForecast(String forecastCode, LocalDateTime pointTime) { // æ¬æå ä½ï¼ç®åç§»å¨å¹³å颿µ // å®é 项ç®åºéæ ML 模åï¼ARIMA/Prophet/LSTMï¼ log.info("[generateForecast][çæé¢æµ] forecastCode={}, pointTime={}, å½å为å ä½å®ç°", forecastCode, pointTime); // åºäºå颿µç¼ç çåå²é¢æµæ°æ®åç®åç§»å¨å¹³åï¼æ å岿°æ®æ¶ä¸ä¼ªé é¶å¼ List<BiForecastDataDO> history = forecastDataMapper.selectRecentByCode(forecastCode, SMA_WINDOW); if (CollUtil.isEmpty(history)) { throw exception(BI_FORECAST_NO_HISTORY); } BigDecimal sum = history.stream() .map(BiForecastDataDO::getForecastValue) .filter(value -> value != null) .reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal avg = sum.divide(BigDecimal.valueOf(history.size()), 4, RoundingMode.HALF_UP); BigDecimal bound = avg.multiply(new BigDecimal("0.10")); BiForecastDataDO forecast = BiForecastDataDO.builder() .forecastCode(forecastCode) .forecastName("è´è·é¢æµ(å ä½)") .forecastName(history.get(0).getForecastName()) .pointTime(pointTime) .forecastValue(BigDecimal.ZERO) .lowerBound(BigDecimal.ZERO) .upperBound(BigDecimal.ZERO) .forecastValue(avg) .lowerBound(avg.subtract(bound)) .upperBound(avg.add(bound)) .confidenceLevel(new BigDecimal("95.00")) .modelVersion("v1.0-placeholder") .modelVersion("v1.0-sma") .build(); forecastDataMapper.insert(forecast); } yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -252,6 +252,7 @@ } // 2.8 设置æä»¤ä¸åæ°é contractVO.setCommandCount(contractCommandService.countByContractId(contractVO.getId())); contractVO.setAuditStatusName(CrmAuditStatusEnum.getNameByStatus(contractVO.getAuditStatus())); }); } yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/purchase/PurchaseOrderApi.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,12 @@ package cn.iocoder.yudao.module.erp.api.purchase; /** * éè´è®¢å API æ¥å£ã * * <p>éè´ä¸å¡å¯¹å¤å¥çº¦ï¼ä¸æ´é² ERP ä¸å¡è·¯ç±ï¼æ§ ERP API ä½ä¸ºå ¼å®¹å¥çº¦ä¿çã</p> */ public interface PurchaseOrderApi extends ErpPurchaseOrderApi { String PREFIX = "/rpc-api/purchase/order"; } yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/purchase/PurchasePlanApi.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,12 @@ package cn.iocoder.yudao.module.erp.api.purchase; /** * éè´è®¡å API æ¥å£ã * * <p>éè´ä¸å¡å¯¹å¤å¥çº¦ï¼æ§ ERP API ä½ä¸ºå ¼å®¹å¥çº¦ä¿çã</p> */ public interface PurchasePlanApi extends ErpPurchasePlanApi { String PREFIX = "/rpc-api/purchase/plan"; } yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/api/purchase/ErpPurchaseOrderApiImpl.java
@@ -28,9 +28,9 @@ * @author è¶ çº§ç®¡çå */ @RestController @RequestMapping(ErpPurchaseOrderApi.PREFIX) @RequestMapping({ErpPurchaseOrderApi.PREFIX, PurchaseOrderApi.PREFIX}) @Validated public class ErpPurchaseOrderApiImpl implements ErpPurchaseOrderApi { public class ErpPurchaseOrderApiImpl implements PurchaseOrderApi { @Resource private ErpPurchaseOrderService purchaseOrderService; yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/api/purchase/ErpPurchasePlanApiImpl.java
@@ -16,7 +16,7 @@ */ @Service @Validated public class ErpPurchasePlanApiImpl implements ErpPurchasePlanApi { public class ErpPurchasePlanApiImpl implements PurchasePlanApi { @Resource private ErpPurchasePlanService purchasePlanService; yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
@@ -51,7 +51,7 @@ @Tag(name = "管çåå° - ERP éè´æ¥ç¥¨") @RestController @RequestMapping("/erp/purchase-invoice") @RequestMapping({"/erp/purchase-invoice", "/purchase/invoice"}) @Validated public class ErpPurchaseInvoiceController { yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java
@@ -47,7 +47,7 @@ @Tag(name = "管çåå° - ERP éè´è®¢å") @RestController @RequestMapping("/erp/purchase-order") @RequestMapping({"/erp/purchase-order", "/purchase/order"}) @Validated public class ErpPurchaseOrderController { yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchasePlanController.java
@@ -48,7 +48,7 @@ @Tag(name = "管çåå° - ERP éè´è®¡å") @RestController @RequestMapping("/erp/purchase-plan") @RequestMapping({"/erp/purchase-plan", "/purchase/plan"}) @Validated public class ErpPurchasePlanController { yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java
@@ -47,7 +47,7 @@ @Tag(name = "管çåå° - ERP éè´ç³è¯·") @RestController @RequestMapping("/erp/purchase-request") @RequestMapping({"/erp/purchase-request", "/purchase/request"}) @Validated public class ErpPurchaseRequestController { yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpSupplierController.java
@@ -33,7 +33,7 @@ @Tag(name = "管çåå° - ERP ä¾åºå") @RestController @RequestMapping("/erp/supplier") @RequestMapping({"/erp/supplier", "/purchase/supplier"}) @Validated public class ErpSupplierController { yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/statistics/ErpPurchaseStatisticsController.java
@@ -26,7 +26,7 @@ @Tag(name = "管çåå° - ERP éè´ç»è®¡") @RestController @RequestMapping("/erp/purchase-statistics") @RequestMapping({"/erp/purchase-statistics", "/purchase/statistics"}) @Validated public class ErpPurchaseStatisticsController { yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/MesProWorkOrderBomController.java
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderItemRespDTO; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; @@ -71,7 +71,7 @@ @Resource private MesWmMaterialStockMapper materialStockMapper; @Resource private ErpPurchaseOrderApi purchaseOrderApi; private PurchaseOrderApi purchaseOrderApi; @PostMapping("/create") @Operation(summary = "å建工å BOM") yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/MesWmArrivalNoticeController.java
@@ -13,8 +13,8 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.MesWmArrivalNoticeSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO; import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO; import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; @@ -48,7 +48,7 @@ @Resource private SrmSupplierApi srmSupplierApi; @Resource private ErpPurchaseOrderApi purchaseOrderApi; private PurchaseOrderApi purchaseOrderApi; @PostMapping("/create") @Operation(summary = "å建å°è´§éç¥å") yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -265,6 +265,7 @@ // ========== MES ç产管ç-å·¥èºè·¯çº¿äº§åï¼1-040-501-200ï¼ ========== ErrorCode PRO_ROUTE_PRODUCT_NOT_EXISTS = new ErrorCode(1_040_501_200, "å·¥èºè·¯çº¿äº§åä¸åå¨"); ErrorCode PRO_ROUTE_PRODUCT_ITEM_DUPLICATE = new ErrorCode(1_040_501_201, "æ¤äº§åå·²é ç½®äºå·¥èºè·¯çº¿"); ErrorCode PRO_ROUTE_PRODUCT_ITEM_TYPE_INVALID = new ErrorCode(1_040_501_202, "å·¥èºè·¯çº¿åªè½å ³è产åç±»åç©æ"); // ========== MES ç产管ç-å·¥èºè·¯çº¿äº§åBOMï¼1-040-501-300ï¼ ========== ErrorCode PRO_ROUTE_PRODUCT_BOM_NOT_EXISTS = new ErrorCode(1_040_501_300, "å·¥èºè·¯çº¿äº§å BOM ä¸åå¨"); ErrorCode PRO_ROUTE_PRODUCT_BOM_DUPLICATE = new ErrorCode(1_040_501_301, "å½å BOM ç©æå¨æ¤å·¥åºå·²ç»é ç½®è¿"); @@ -274,6 +275,7 @@ ErrorCode PRO_WORK_ORDER_CODE_DUPLICATE = new ErrorCode(1_040_502_001, "ç产工åç¼ç å·²åå¨"); ErrorCode PRO_WORK_ORDER_NOT_PREPARE = new ErrorCode(1_040_502_002, "åªæèç¨¿ç¶æçå·¥åæè½æ§è¡æ¤æä½"); ErrorCode PRO_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_502_003, "åªæå·²ç¡®è®¤ç¶æçå·¥åæè½æ§è¡æ¤æä½"); ErrorCode PRO_WORK_ORDER_PRODUCTION_NOT_COMPLETE = new ErrorCode(1_040_502_007, "å·¥åå®é äº§åºæªè¾¾å°è®¡åæ°éï¼ä¸è½å®æ"); ErrorCode PRO_WORK_ORDER_HAS_CHILDREN = new ErrorCode(1_040_502_004, "åå¨åå·¥åï¼æ æ³å é¤"); ErrorCode PRO_WORK_ORDER_PRODUCT_MISMATCH = new ErrorCode(1_040_502_005, "å½å产åç©æä¸ç产工å产åä¸ä¸è´"); ErrorCode PRO_WORK_ORDER_SCHEDULE_QUANTITY_EXCEED = new ErrorCode(1_040_502_006, "æäº§æ°éè¶ éï¼å·¥å{}(计å{}ï¼å·²æäº§{}ï¼æ¬æ¬¡æäº§{})"); @@ -356,6 +358,7 @@ ErrorCode PRO_MPS_CODE_DUPLICATE = new ErrorCode(1_040_509_006, "MPS ç¼ç å·²åå¨"); ErrorCode PRO_MPS_HAS_WORK_ORDER = new ErrorCode(1_040_509_007, "MPS å·²å ³èç产工åï¼æ æ³å é¤"); ErrorCode PRO_MPS_MES_PRODUCT_NOT_EXISTS = new ErrorCode(1_040_509_008, "MES 产åä¸åå¨ï¼æ æ³å建 MPSï¼äº§åï¼{}"); ErrorCode PRO_MPS_PRODUCT_TYPE_INVALID = new ErrorCode(1_040_509_009, "æç¨äº§åå¿ é¡»æ¯äº§åç±»åï¼ç¦æ¢ä½¿ç¨ç©æ"); // ========== MES è´¨é管ç-è´¨æ£æ¹æ¡ï¼1-040-600-000ï¼ ========== ErrorCode QC_TEMPLATE_NOT_EXISTS = new ErrorCode(1_040_600_000, "è´¨æ£æ¹æ¡ä¸åå¨"); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/product/MesPdProductServiceImpl.java
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.pd.product.MesPdProductDO; import cn.iocoder.yudao.module.mes.dal.mysql.pd.product.MesPdProductMapper; import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; import cn.iocoder.yudao.module.mes.enums.pd.MesPdAuditStatusEnum; import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; import cn.iocoder.yudao.module.mes.enums.pd.MesPdAuditStatusEnum; import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; @@ -144,8 +145,10 @@ private void fillDictName(MesPdProductRespVO respVO) { respVO.setArchiveTypeName(DictFrameworkUtils.parseDictDataLabel( DictTypeConstants.MES_PD_PRODUCT_ARCHIVE_TYPE, respVO.getArchiveType())); respVO.setAuditStatusName(DictFrameworkUtils.parseDictDataLabel( DictTypeConstants.MES_PD_PRODUCT_AUDIT_STATUS, respVO.getAuditStatus())); String auditStatusName = DictFrameworkUtils.parseDictDataLabel( DictTypeConstants.MES_PD_PRODUCT_AUDIT_STATUS, respVO.getAuditStatus()); respVO.setAuditStatusName(auditStatusName != null ? auditStatusName : MesPdAuditStatusEnum.getNameByStatus(respVO.getAuditStatus())); } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/maintenanceplan/MesProMaintenancePlanServiceImpl.java
@@ -4,7 +4,7 @@ import cn.hutool.core.date.DateUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchasePlanApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchasePlanApi; import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchasePlanCreateReqDTO; import cn.iocoder.yudao.module.mes.controller.admin.pro.maintenanceplan.vo.MesProMaintenancePlanPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.maintenanceplan.vo.MesProMaintenancePlanSaveReqVO; @@ -74,7 +74,7 @@ private MesMdItemService itemService; @Resource private ErpPurchasePlanApi erpPurchasePlanApi; private PurchasePlanApi purchasePlanApi; @Resource private MesProWorkOrderService workOrderService; @@ -199,7 +199,7 @@ createReqDTO.setPlanDate(plan.getPlanDate()); createReqDTO.setRemark("æ¥æºè®¡å: " + plan.getCode()); createReqDTO.setItems(items); return erpPurchasePlanApi.createPurchasePlan(createReqDTO); return purchasePlanApi.createPurchasePlan(createReqDTO); } @Override yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/mps/MesProMpsServiceImpl.java
@@ -17,6 +17,10 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; import cn.iocoder.yudao.module.mes.enums.md.MesMdItemTypeEnum; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; import cn.iocoder.yudao.module.mes.enums.pro.MesProMpsStatusEnum; @@ -74,6 +78,8 @@ @Resource private MesMdItemService itemService; @Resource private MesMdItemTypeService itemTypeService; @Resource private MesMdAutoCodeRecordService autoCodeRecordService; @Resource private CrmCustomerApi customerApi; @@ -94,11 +100,12 @@ Long mdmItemId, String productName, BigDecimal quantity, Long clientId, String requestDate, String remark) { // 1. æ ¹æ® MDM ç©æ ID æ¥æ¾ MES 产å cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO mesItem = itemService.getItemByMdmItemId(mdmItemId); MesMdItemDO mesItem = itemService.getItemByMdmItemId(mdmItemId); if (mesItem == null) { // MES 产åä¸åå¨ï¼æåºå¼å¸¸å¹¶å å«äº§ååç§°æç¤º throw exception(PRO_MPS_MES_PRODUCT_NOT_EXISTS, productName != null ? productName : mdmItemId); } validateProductItem(mesItem.getId()); // 2. çæ MPS ç¼ç String code = generateMpsCode(); @@ -138,8 +145,8 @@ @Override @Transactional(rollbackFor = Exception.class) public Long createMps(MesProMpsSaveReqVO createReqVO) { // æ ¡éªäº§ååå¨ itemService.validateItemExists(createReqVO.getProductId()); // æ ¡éªäº§ååå¨ãå¯ç¨ä¸ä¸ºäº§åç±»å validateProductItem(createReqVO.getProductId()); // 妿æªå¡«åç¼ç ï¼èªå¨çæ if (StrUtil.isBlank(createReqVO.getCode())) { @@ -165,6 +172,8 @@ public void updateMps(MesProMpsSaveReqVO updateReqVO) { // æ ¡éªåå¨ + èç¨¿ç¶æ validateMpsExistsAndDraft(updateReqVO.getId()); // æ ¡éªäº§ååå¨ãå¯ç¨ä¸ä¸ºäº§åç±»å validateProductItem(updateReqVO.getProductId()); // æ ¡éªç¼ç å¯ä¸ validateMpsCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); @@ -509,6 +518,17 @@ } /** * æ ¡éªäº§ååå¨ãå¯ç¨ä¸ä¸ºäº§åç±»å */ private void validateProductItem(Long itemId) { MesMdItemDO item = itemService.validateItemExistsAndEnable(itemId); MesMdItemTypeDO itemType = itemTypeService.getItemType(item.getItemTypeId()); if (itemType == null || !MesMdItemTypeEnum.isProduct(itemType.getItemOrProduct())) { throw exception(PRO_MPS_PRODUCT_TYPE_INVALID); } } /** * æ ¹æ® MPS å建ç产工å */ private Long createWorkOrderFromMps(MesProMpsDO mps, BigDecimal quantity) { yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductServiceImpl.java
@@ -4,7 +4,12 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.route.MesProRouteProductMapper; import cn.iocoder.yudao.module.mes.enums.md.MesMdItemTypeEnum; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -34,12 +39,18 @@ @Resource @Lazy private MesProRouteProductBomService routeProductBomService; @Resource private MesMdItemService itemService; @Resource private MesMdItemTypeService itemTypeService; @Override public Long createRouteProduct(MesProRouteProductSaveReqVO createReqVO) { // 1.0 å·²å¯ç¨çå·¥èºè·¯çº¿ï¼ä¸å 许æä½ routeService.validateRouteNotEnable(createReqVO.getRouteId()); // 1.1 æ ¡éªäº§åå¯ä¸æ§ï¼ä¸ä¸ªäº§ååªè½å ³è䏿¡å·¥èºè·¯çº¿ï¼ // 1.1 æ ¡éªäº§ååå¨ãå¯ç¨ä¸ç±»åæ£ç¡® validateProductItem(createReqVO.getItemId()); // 1.2 æ ¡éªäº§åå¯ä¸æ§ï¼ä¸ä¸ªäº§ååªè½å ³è䏿¡å·¥èºè·¯çº¿ï¼ validateItemUnique(null, createReqVO.getItemId()); // 2. æå ¥ @@ -54,7 +65,9 @@ routeService.validateRouteNotEnable(updateReqVO.getRouteId()); // 1.1 æ ¡éªåå¨ validateRouteProductExists(updateReqVO.getId()); // 1.2 æ ¡éªäº§åå¯ä¸æ§ // 1.2 æ ¡éªäº§ååå¨ãå¯ç¨ä¸ç±»åæ£ç¡® validateProductItem(updateReqVO.getItemId()); // 1.3 æ ¡éªäº§åå¯ä¸æ§ validateItemUnique(updateReqVO.getId(), updateReqVO.getItemId()); // 2. æ´æ° @@ -89,6 +102,14 @@ } } private void validateProductItem(Long itemId) { MesMdItemDO item = itemService.validateItemExistsAndEnable(itemId); MesMdItemTypeDO itemType = itemTypeService.getItemType(item.getItemTypeId()); if (itemType == null || !MesMdItemTypeEnum.isProduct(itemType.getItemOrProduct())) { throw exception(PRO_ROUTE_PRODUCT_ITEM_TYPE_INVALID); } } private void validateItemUnique(Long id, Long itemId) { MesProRouteProductDO existing = routeProductMapper.selectByItemId(itemId); if (existing == null) { yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderServiceImpl.java
@@ -225,6 +225,20 @@ if (ObjUtil.notEqual(workOrder.getStatus(), MesProWorkOrderStatusEnum.CONFIRMED.getStatus())) { throw exception(PRO_WORK_ORDER_NOT_CONFIRMED); } if (workOrder.getQuantityProduced() == null || workOrder.getQuantity() == null || workOrder.getQuantityProduced().compareTo(workOrder.getQuantity()) < 0) { throw exception(PRO_WORK_ORDER_PRODUCTION_NOT_COMPLETE); } // æ ¡éªæ¯ä¸ªä»»å¡çå®é äº§åºæ¯å¦å·²è¾¾æè®¡åæ°éï¼ä»»å¡ç¶æåªæå¨å·¥å宿æ¶ç±çº§èæ¹æ³ç½®ä¸ºå·²å®æï¼ä¸è½å¨æ¤æ ¡éªç¶æï¼ List<MesProTaskDO> tasks = taskService.getTaskListByWorkOrderIds(Collections.singletonList(id)); boolean hasUnfinishedTask = CollUtil.isEmpty(tasks) || tasks.stream().anyMatch(task -> task.getProducedQuantity() == null || task.getQuantity() == null || task.getProducedQuantity().compareTo(task.getQuantity()) < 0); if (hasUnfinishedTask) { throw exception(PRO_WORK_ORDER_PRODUCTION_NOT_COMPLETE); } // 2. 级è宿ææå ³èä»»å¡ taskService.finishTaskByOrderId(id); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
@@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeMapper; import cn.iocoder.yudao.module.mes.enums.wm.MesWmArrivalNoticeStatusEnum; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi; import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO; import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderItemRespDTO; @@ -51,7 +51,7 @@ private SrmSupplierApi srmSupplierApi; @Resource private ErpPurchaseOrderApi purchaseOrderApi; private PurchaseOrderApi purchaseOrderApi; @Resource private MesMdmItemService mdmItemService; yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
@@ -25,7 +25,7 @@ import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi; import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; @@ -81,7 +81,7 @@ private BpmProcessInstanceApi processInstanceApi; @Resource private ErpPurchaseOrderApi purchaseOrderApi; private PurchaseOrderApi purchaseOrderApi; @Resource private MdmItemApi mdmItemApi; yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java
@@ -3,7 +3,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderCreateReqDTO; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; @@ -61,7 +61,7 @@ private MdmItemApi mdmItemApi; @Resource private ErpPurchaseOrderApi erpPurchaseOrderApi; private PurchaseOrderApi purchaseOrderApi; @Resource private SrmSupplierApplyService supplierApplyService; @@ -233,12 +233,12 @@ createReq.setItems(orderItems); createReq.setRemark("SRM 宿 èªå¨çæ, 宿 ç¼å·: " + award.getAwardNo()); Long purchaseOrderId = erpPurchaseOrderApi.createPurchaseOrder(createReq).getCheckedData(); Long purchaseOrderId = purchaseOrderApi.createPurchaseOrder(createReq).getCheckedData(); // è·åéè´è®¢åå· String purchaseOrderNo = null; try { purchaseOrderNo = erpPurchaseOrderApi.getPurchaseOrder(purchaseOrderId) purchaseOrderNo = purchaseOrderApi.getPurchaseOrder(purchaseOrderId) .getCheckedData().getNo(); } catch (Exception e) { log.warn("[generatePurchaseOrder] è·åéè´è®¢åå·å¤±è´¥ï¼purchaseOrderId={}", purchaseOrderId, e); yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectServiceImpl.java
@@ -3,7 +3,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi; import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderCreateReqDTO; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; @@ -66,7 +66,7 @@ @Resource private MdmItemApi mdmItemApi; @Resource private ErpPurchaseOrderApi erpPurchaseOrderApi; private PurchaseOrderApi purchaseOrderApi; @Resource private SrmSupplierApplyService supplierApplyService; @Resource @@ -376,12 +376,12 @@ createReq.setItems(orderItems); createReq.setRemark("SRM ç®ææææ èªå¨çæ, 宿 ç¼å·: " + award.getAwardNo()); Long purchaseOrderId = erpPurchaseOrderApi.createPurchaseOrder(createReq).getCheckedData(); Long purchaseOrderId = purchaseOrderApi.createPurchaseOrder(createReq).getCheckedData(); // è·åéè´è®¢åå· String purchaseOrderNo = null; try { purchaseOrderNo = erpPurchaseOrderApi.getPurchaseOrder(purchaseOrderId) purchaseOrderNo = purchaseOrderApi.getPurchaseOrder(purchaseOrderId) .getCheckedData().getNo(); } catch (Exception e) { log.warn("[generatePurchaseOrderForSimple] è·åéè´è®¢åå·å¤±è´¥ï¼purchaseOrderId={}", purchaseOrderId, e);