From 5140e16bd1cb2bdf974d47a4342f9e27ef804655 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期六, 18 七月 2026 15:54:07 +0800
Subject: [PATCH] feat(erp): 增加销售订单MPS集成与发货通知单控制功能
---
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java | 43 ++++++
/dev/null | 160 ----------------------
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java | 92 +++++++++++++
yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApi.java | 10 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java | 8
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApiImpl.java | 35 +++++
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java | 6
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpSupplierServiceImpl.java | 4
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java | 12 +
9 files changed, 202 insertions(+), 168 deletions(-)
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java
index ad74f35..1280ab6 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java
@@ -18,6 +18,7 @@
import cn.iocoder.yudao.module.erp.service.sale.ErpSaleOrderService;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
import cn.iocoder.yudao.module.mes.api.salesnotice.MesWmSalesNoticeApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@@ -58,6 +59,8 @@
private AdminUserApi adminUserApi;
@Resource
private MesWmSalesNoticeApi salesNoticeApi;
+ @Resource
+ private MesProMpsApi mpsApi;
@PostMapping("/create")
@Operation(summary = "鍒涘缓閿�鍞鍗�")
@@ -171,6 +174,40 @@
// 1.5 鍙戣揣閫氱煡鍗曚俊鎭�
Map<Long, Boolean> salesNoticeMap = salesNoticeApi.checkSalesNoticeBySaleOrderIds(
convertSet(pageResult.getList(), ErpSaleOrderDO::getId));
+ // 1.6 妫�鏌ユ槸鍚﹀彲浠ョ敓鎴愬彂璐ч�氱煡鍗曪紙闇�瑕佺敓浜х殑鏄庣粏瀵瑰簲鐨� MPS 鏄惁宸插畬鎴愶級
+ // 绛涢�夊嚭闇�瑕佺敓浜х殑鏄庣粏ID
+ List<Long> needProductionItemIds = saleOrderItemList.stream()
+ .filter(item -> item.getNeedProduction() != null && item.getNeedProduction() == 1)
+ .map(ErpSaleOrderItemDO::getId)
+ .toList();
+ Map<Long, Boolean> canCreateSalesNoticeMap = new java.util.HashMap<>();
+ if (!needProductionItemIds.isEmpty()) {
+ // 鎸夎鍗曞垎缁勬槑缁咺D
+ Map<Long, List<Long>> orderItemIdsMap = new java.util.HashMap<>();
+ for (ErpSaleOrderItemDO item : saleOrderItemList) {
+ orderItemIdsMap.computeIfAbsent(item.getOrderId(), k -> new java.util.ArrayList<>())
+ .add(item.getId());
+ }
+ // 妫�鏌ユ瘡涓鍗�
+ for (Map.Entry<Long, List<Long>> entry : orderItemIdsMap.entrySet()) {
+ List<Long> itemIds = entry.getValue().stream()
+ .filter(id -> {
+ ErpSaleOrderItemDO item = saleOrderItemList.stream()
+ .filter(i -> i.getId().equals(id))
+ .findFirst().orElse(null);
+ return item != null && item.getNeedProduction() != null && item.getNeedProduction() == 1;
+ }
+ ).toList();
+ if (itemIds.isEmpty()) {
+ canCreateSalesNoticeMap.put(entry.getKey(), true);
+ } else {
+ canCreateSalesNoticeMap.put(entry.getKey(), mpsApi.checkCanCreateSalesNotice(itemIds));
+ }
+ }
+ } else {
+ // 娌℃湁闇�瑕佺敓浜х殑鏄庣粏锛岄兘鍙互鐢熸垚鍙戣揣閫氱煡鍗�
+ pageResult.getList().forEach(order -> canCreateSalesNoticeMap.put(order.getId(), true));
+ }
// 2. 寮�濮嬫嫾鎺�
return BeanUtils.toBean(pageResult, ErpSaleOrderRespVO.class, saleOrder -> {
saleOrder.setItems(BeanUtils.toBean(saleOrderItemMap.get(saleOrder.getId()), ErpSaleOrderRespVO.Item.class,
@@ -181,6 +218,12 @@
MapUtils.findAndThen(userMap, Long.parseLong(saleOrder.getCreator()), user -> saleOrder.setCreatorName(user.getNickname()));
// 璁剧疆鏄惁宸茬敓鎴愬彂璐ч�氱煡鍗�
saleOrder.setHasSalesNotice(salesNoticeMap.getOrDefault(saleOrder.getId(), false));
+ // 璁剧疆鏄惁鍙互鐢熸垚鍙戣揣閫氱煡鍗�
+ saleOrder.setCanCreateSalesNotice(canCreateSalesNoticeMap.getOrDefault(saleOrder.getId(), true));
+ // 璁剧疆鏄惁鏈夐渶瑕佺敓浜х殑鏄庣粏
+ boolean hasNeedProduction = saleOrder.getItems().stream()
+ .anyMatch(item -> item.getNeedProduction() != null && item.getNeedProduction() == 1);
+ saleOrder.setNeedProduction(hasNeedProduction ? 1 : 0);
});
}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
index 34085c4..63d2389 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
@@ -109,6 +109,12 @@
@Schema(description = "鏄惁宸茬敓鎴愬彂璐ч�氱煡鍗�", example = "false")
private Boolean hasSalesNotice;
+ @Schema(description = "鏄惁鍙互鐢熸垚鍙戣揣閫氱煡鍗曪紙鏈夐渶瑕佺敓浜т笖鏈畬鎴愮殑鏄庣粏鏃朵负 false锛�", example = "true")
+ private Boolean canCreateSalesNotice;
+
+ @Schema(description = "鏄惁鏈夐渶瑕佺敓浜х殑鏄庣粏锛�0=鍚� 1=鏄級", example = "1")
+ private Integer needProduction;
+
@Data
public static class Item {
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpSupplierServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpSupplierServiceImpl.java
index 64db7cd..9e56f4a 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpSupplierServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpSupplierServiceImpl.java
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.erp.service.purchase;
+import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -78,6 +79,9 @@
@Override
public List<ErpSupplierDO> getSupplierList(Collection<Long> ids) {
+ if (CollUtil.isEmpty(ids)) {
+ return CollUtil.newArrayList();
+ }
return supplierMapper.selectByIds(ids);
}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
index 5018ce3..a9ad090 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
@@ -17,13 +17,20 @@
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
import cn.iocoder.yudao.module.erp.api.sale.enums.ErpSaleOrderOutStatusEnum;
import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
+import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsCreateReqDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -40,6 +47,7 @@
*/
@Service
@Validated
+@Slf4j
public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
@Resource
@@ -59,6 +67,11 @@
@Resource
private AdminUserApi adminUserApi;
+
+ @Resource
+ private MdmItemApi mdmItemApi;
+ @Resource
+ private MesProMpsApi mpsApi;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -157,6 +170,85 @@
if (updateCount == 0) {
throw exception(approve ? SALE_ORDER_APPROVE_FAIL : SALE_ORDER_PROCESS_FAIL);
}
+
+ // 3. 瀹℃牳閫氳繃鏃讹紝涓洪渶瑕佺敓浜х殑鏄庣粏鍒涘缓 MPS
+ if (approve) {
+ createMpsForSaleOrder(id, saleOrder);
+ }
+ }
+
+ /**
+ * 涓洪攢鍞鍗曚腑闇�瑕佺敓浜х殑鏄庣粏鍒涘缓 MPS
+ *
+ * @param orderId 閿�鍞鍗曠紪鍙�
+ * @param saleOrder 閿�鍞鍗�
+ */
+ private void createMpsForSaleOrder(Long orderId, ErpSaleOrderDO saleOrder) {
+ List<ErpSaleOrderItemDO> items = saleOrderItemMapper.selectListByOrderId(orderId);
+ if (CollUtil.isEmpty(items)) {
+ return;
+ }
+
+ int mpsCount = 0;
+ for (ErpSaleOrderItemDO item : items) {
+ if (item.getNeedProduction() == null || item.getNeedProduction() != 1) {
+ continue;
+ }
+ try {
+ Long mpsId = createMpsForSaleOrderItem(saleOrder, item);
+ if (mpsId != null) {
+ mpsCount++;
+ // 鏇存柊閿�鍞鍗曟槑缁嗙殑 MPS 鍏宠仈
+ saleOrderItemMapper.updateById(new ErpSaleOrderItemDO()
+ .setId(item.getId())
+ .setMpsId(mpsId));
+ }
+ } catch (Exception e) {
+ log.error("[createMpsForSaleOrder] 鍒涘缓 MPS 澶辫触锛宻aleOrderItemId={}", item.getId(), e);
+ }
+ }
+ log.info("[createMpsForSaleOrder] 閿�鍞鍗�({}) 瀹℃牳瀹屾垚锛屽垱寤� MPS {} 鏉�", orderId, mpsCount);
+ }
+
+ /**
+ * 涓洪攢鍞鍗曟槑缁嗗垱寤� MPS
+ */
+ private Long createMpsForSaleOrderItem(ErpSaleOrderDO saleOrder, ErpSaleOrderItemDO item) {
+ // 鑾峰彇 MDM 鐗╂枡淇℃伅锛堢敤浜庤幏鍙栦骇鍝佸悕绉帮級
+ String productName = null;
+ try {
+ MdmItemRespDTO mdmItem = mdmItemApi.getItem(item.getProductId()).getCheckedData();
+ if (mdmItem != null) {
+ productName = mdmItem.getName();
+ }
+ } catch (Exception e) {
+ log.warn("[createMpsForSaleOrderItem] 鑾峰彇 MDM 鐗╂枡淇℃伅澶辫触锛宲roductId={}", item.getProductId(), e);
+ }
+
+ MesProMpsCreateReqDTO createReqDTO = new MesProMpsCreateReqDTO();
+ createReqDTO.setSaleOrderId(saleOrder.getId());
+ createReqDTO.setSaleOrderNo(saleOrder.getNo());
+ createReqDTO.setSaleOrderItemId(item.getId());
+ createReqDTO.setMdmItemId(item.getProductId());
+ createReqDTO.setProductName(productName);
+ createReqDTO.setQuantity(item.getCount());
+ createReqDTO.setClientId(saleOrder.getCustomerId());
+ createReqDTO.setRequestDate(formatRequestDate(saleOrder.getOrderTime()));
+ createReqDTO.setRemark("鑷姩鐢熸垚锛屾潵鑷攢鍞鍗曪細" + saleOrder.getNo());
+
+ Long mpsId = mpsApi.createMps(createReqDTO);
+ log.info("[createMpsForSaleOrderItem] MPS 鍒涘缓鎴愬姛锛宮psId={}, saleOrderItemId={}", mpsId, item.getId());
+ return mpsId;
+ }
+
+ /**
+ * 鏍煎紡鍖栭渶姹傛棩鏈�
+ */
+ private String formatRequestDate(LocalDateTime dateTime) {
+ if (dateTime == null) {
+ return null;
+ }
+ return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
@Override
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/listener/ErpSaleOrderStatusListener.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/listener/ErpSaleOrderStatusListener.java
deleted file mode 100644
index f068d75..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/listener/ErpSaleOrderStatusListener.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.sale.listener;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderItemDO;
-import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderItemMapper;
-import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderMapper;
-import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
-import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
-import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
-import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
-import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsCreateReqDTO;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.List;
-
-/**
- * 閿�鍞鍗曞鎵圭姸鎬佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝瀹℃牳閫氳繃鏃惰嚜鍔ㄥ垱寤� MPS
- *
- * @author 鑺嬮亾婧愮爜
- */
-@Component
-@Slf4j
-public class ErpSaleOrderStatusListener extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
-
- /**
- * 閿�鍞鍗曞鎵规祦绋嬪畾涔� Key
- */
- private static final String PROCESS_DEFINITION_KEY = "sale_order_approve";
-
- @Resource
- private ErpSaleOrderMapper saleOrderMapper;
- @Resource
- private ErpSaleOrderItemMapper saleOrderItemMapper;
- @Resource
- private MesProMpsApi mpsApi;
- @Resource
- private MdmItemApi mdmItemApi;
-
- @Override
- protected String getProcessDefinitionKey() {
- return PROCESS_DEFINITION_KEY;
- }
-
- @Override
- protected void onEvent(BpmProcessInstanceStatusEvent event) {
- Long orderId;
- try {
- orderId = Long.parseLong(event.getBusinessKey());
- } catch (NumberFormatException e) {
- log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勯攢鍞鍗曠紪鍙�", event.getBusinessKey());
- return;
- }
-
- log.info("[onEvent] 鏀跺埌 BPM 瀹℃壒浜嬩欢锛宱rderId={}, status={}", orderId, event.getStatus());
-
- // 鍙湁瀹℃壒閫氳繃鎵嶅垱寤� MPS
- if (!BpmTaskStatusEnum.APPROVE.getStatus().equals(event.getStatus())) {
- return;
- }
-
- try {
- // 1. 鑾峰彇閿�鍞鍗�
- ErpSaleOrderDO saleOrder = saleOrderMapper.selectById(orderId);
- if (saleOrder == null) {
- log.warn("[onEvent] 閿�鍞鍗曚笉瀛樺湪锛宱rderId={}", orderId);
- return;
- }
-
- // 2. 鑾峰彇閿�鍞鍗曟槑缁�
- List<ErpSaleOrderItemDO> items = saleOrderItemMapper.selectListByOrderId(orderId);
- if (CollUtil.isEmpty(items)) {
- log.info("[onEvent] 閿�鍞鍗�({}) 娌℃湁鏄庣粏锛屾棤闇�鍒涘缓 MPS", orderId);
- return;
- }
-
- // 3. 鏇存柊璁㈠崟鐘舵�佷负宸插鏍�
- saleOrderMapper.updateById(new ErpSaleOrderDO()
- .setId(orderId)
- .setStatus(ErpAuditStatus.APPROVE.getStatus()));
-
- // 4. 閬嶅巻鏄庣粏锛屼负闇�瑕佺敓浜х殑鏄庣粏鍒涘缓 MPS
- int mpsCount = 0;
- for (ErpSaleOrderItemDO item : items) {
- if (item.getNeedProduction() == null || item.getNeedProduction() != 1) {
- continue;
- }
- try {
- Long mpsId = createMpsForSaleOrderItem(saleOrder, item);
- if (mpsId != null) {
- mpsCount++;
- // 鏇存柊閿�鍞鍗曟槑缁嗙殑 MPS 鍏宠仈
- saleOrderItemMapper.updateById(new ErpSaleOrderItemDO()
- .setId(item.getId())
- .setMpsId(mpsId));
- }
- } catch (Exception e) {
- log.error("[onEvent] 鍒涘缓 MPS 澶辫触锛宻aleOrderItemId={}", item.getId(), e);
- }
- }
-
- log.info("[onEvent] 閿�鍞鍗�({}) 瀹℃壒瀹屾垚锛屽垱寤� MPS {} 鏉�", orderId, mpsCount);
- } catch (Exception e) {
- log.error("[onEvent] 澶勭悊閿�鍞鍗曞鎵逛簨浠跺け璐ワ紝orderId={}", orderId, e);
- }
- }
-
- /**
- * 涓洪攢鍞鍗曟槑缁嗗垱寤� MPS
- *
- * 娉ㄦ剰锛氶攢鍞鍗曟槑缁嗙殑 productId 鏄� MDM 鐗╂枡 ID锛岄渶瑕佹槧灏勫埌 MES 浜у搧
- */
- private Long createMpsForSaleOrderItem(ErpSaleOrderDO saleOrder, ErpSaleOrderItemDO item) {
- // 鑾峰彇 MDM 鐗╂枡淇℃伅锛堢敤浜庤幏鍙栦骇鍝佸悕绉帮級
- String productName = null;
- try {
- MdmItemRespDTO mdmItem = mdmItemApi.getItem(item.getProductId()).getCheckedData();
- if (mdmItem != null) {
- productName = mdmItem.getName();
- }
- } catch (Exception e) {
- log.warn("[createMpsForSaleOrderItem] 鑾峰彇 MDM 鐗╂枡淇℃伅澶辫触锛宲roductId={}", item.getProductId(), e);
- }
-
- MesProMpsCreateReqDTO createReqDTO = new MesProMpsCreateReqDTO();
- createReqDTO.setSaleOrderId(saleOrder.getId());
- createReqDTO.setSaleOrderNo(saleOrder.getNo());
- createReqDTO.setSaleOrderItemId(item.getId());
- createReqDTO.setMdmItemId(item.getProductId()); // 閿�鍞鍗曟槑缁嗙殑 productId 鏄� MDM 鐗╂枡 ID
- createReqDTO.setProductName(productName); // 浜у搧鍚嶇О鐢ㄤ簬閿欒鎻愮ず
- createReqDTO.setQuantity(item.getCount());
- createReqDTO.setClientId(saleOrder.getCustomerId());
- createReqDTO.setRequestDate(formatRequestDate(saleOrder.getOrderTime()));
- createReqDTO.setRemark("鑷姩鐢熸垚锛屾潵鑷攢鍞鍗曪細" + saleOrder.getNo());
-
- Long mpsId = mpsApi.createMps(createReqDTO);
- log.info("[createMpsForSaleOrderItem] MPS 鍒涘缓鎴愬姛锛宮psId={}, saleOrderItemId={}", mpsId, item.getId());
- return mpsId;
- }
-
- /**
- * 鏍煎紡鍖栭渶姹傛棩鏈�
- */
- private String formatRequestDate(LocalDateTime dateTime) {
- if (dateTime == null) {
- return null;
- }
- return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
- }
-
-}
\ No newline at end of file
diff --git a/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApi.java b/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApi.java
index 6d75372..55de681 100644
--- a/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApi.java
+++ b/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApi.java
@@ -46,4 +46,14 @@
*/
List<MesProMpsRespDTO> getMpsListBySaleOrderItemIds(List<Long> saleOrderItemIds);
+ /**
+ * 妫�鏌ラ攢鍞鍗曟槸鍚﹀彲浠ョ敓鎴愬彂璐ч�氱煡鍗�
+ *
+ * 瑙勫垯锛氬鏋滄湁闇�瑕佺敓浜х殑鏄庣粏锛屽搴旂殑 MPS 蹇呴』宸插畬鎴愶紙status=2锛夋垨宸插彇娑堬紙status=3锛�
+ *
+ * @param saleOrderItemIds 閿�鍞鍗曟槑缁咺D鍒楄〃
+ * @return true=鍙互鐢熸垚鍙戣揣閫氱煡鍗曪紝false=涓嶅彲浠�
+ */
+ Boolean checkCanCreateSalesNotice(List<Long> saleOrderItemIds);
+
}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApiImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApiImpl.java
index ddd0f82..94c009c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApiImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/mps/MesProMpsApiImpl.java
@@ -1,9 +1,11 @@
package cn.iocoder.yudao.module.mes.api.mps;
+import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsCreateReqDTO;
import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.mps.MesProMpsDO;
+import cn.iocoder.yudao.module.mes.enums.pro.MesProMpsStatusEnum;
import cn.iocoder.yudao.module.mes.service.pro.mps.MesProMpsService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -11,6 +13,7 @@
import java.util.Collections;
import java.util.List;
+import java.util.Map;
/**
* MPS API 瀹炵幇绫�
@@ -60,4 +63,36 @@
return BeanUtils.toBean(mpsList, MesProMpsRespDTO.class);
}
+ @Override
+ public Boolean checkCanCreateSalesNotice(List<Long> saleOrderItemIds) {
+ if (CollUtil.isEmpty(saleOrderItemIds)) {
+ return true;
+ }
+ List<MesProMpsDO> mpsList = mpsService.getMpsListBySaleOrderItemIds(saleOrderItemIds);
+ // 鏋勫缓 saleOrderItemId -> MPS 鐨勬槧灏�
+ Map<Long, MesProMpsDO> mpsMap = new java.util.HashMap<>();
+ for (MesProMpsDO mps : mpsList) {
+ if (mps.getSaleOrderItemId() != null) {
+ mpsMap.put(mps.getSaleOrderItemId(), mps);
+ }
+ }
+ // 妫�鏌ユ瘡涓攢鍞鍗曟槑缁嗭細
+ // - 濡傛灉 MPS 涓嶅瓨鍦細涓嶈兘鐢熸垚鍙戣揣閫氱煡鍗�
+ // - 濡傛灉 MPS 瀛樺湪涓旂姸鎬佷负鑽夌/宸蹭笅鍙戯細涓嶈兘鐢熸垚鍙戣揣閫氱煡鍗�
+ // - 濡傛灉 MPS 瀛樺湪涓旂姸鎬佷负宸插畬鎴�/宸插彇娑堬細鍙互鐢熸垚鍙戣揣閫氱煡鍗�
+ for (Long itemId : saleOrderItemIds) {
+ MesProMpsDO mps = mpsMap.get(itemId);
+ if (mps == null) {
+ // MPS 涓嶅瓨鍦紝涓嶈兘鐢熸垚鍙戣揣閫氱煡鍗�
+ return false;
+ }
+ if (mps.getStatus().equals(MesProMpsStatusEnum.DRAFT.getStatus())
+ || mps.getStatus().equals(MesProMpsStatusEnum.ISSUED.getStatus())) {
+ // MPS 鏈畬鎴愶紝涓嶈兘鐢熸垚鍙戣揣閫氱煡鍗�
+ return false;
+ }
+ }
+ return true;
+ }
+
}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
index b392411..78f370b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
@@ -13,7 +13,6 @@
import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
@@ -57,9 +56,6 @@
@Resource
@Lazy
private MesQcDefectRecordService defectRecordService;
- @Resource
- @Lazy
- private MesMdItemService itemService;
@Resource
@Lazy
private MesWmProductSalesLineService productSalesLineService;
@@ -121,8 +117,8 @@
// 鏍¢獙缂栧彿鍞竴
validateOqcCodeUnique(reqVO.getId(), reqVO.getCode());
// 鏍¢獙鐗╂枡銆佹娴嬩汉鍛樺瓨鍦�
- // 娉細瀹㈡埛 ID 鏉ヨ嚜 CRM锛屼笉闇�瑕佸湪 MES 涓牎楠�
- itemService.validateItemExists(reqVO.getItemId());
+ // 娉細鐗╂枡 ID 鏉ヨ嚜 MDM锛屽鎴� ID 鏉ヨ嚜 CRM
+ mdmItemApi.validateItemExists(reqVO.getItemId());
adminUserApi.validateUser(reqVO.getInspectorUserId());
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
index 17d0dc8..031dc5d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
@@ -100,12 +100,20 @@
reqDTO.getItemId(), reqDTO.getWarehouseId(), reqDTO.getLocationId(), reqDTO.getAreaId(),
reqDTO.getBatchId(), reqDTO.getBatchCode(), reqDTO.getVendorId(), reqDTO.getReceiptTime());
} else {
- // 鍑哄簱浜嬪姟锛氬簱瀛樿褰曞繀椤诲凡瀛樺湪锛屼笉鍏佽鑷姩鍒涘缓
+ // 鍑哄簱浜嬪姟锛氬簱瀛樿褰曞繀椤诲凡瀛樺湪锛屼笉鍏佽鑷姩鍒涘缓锛堥櫎闈� checkFlag=false 鍏佽璐熷簱瀛橈級
materialStock = materialStockService.getMaterialStockByCompositeKey(
reqDTO.getItemId(), reqDTO.getWarehouseId(), reqDTO.getLocationId(), reqDTO.getAreaId(),
reqDTO.getBatchId(), reqDTO.getVendorId());
if (materialStock == null) {
- throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
+ // checkFlag=false 鏃跺厑璁歌礋搴撳瓨锛岃嚜鍔ㄥ垱寤哄簱瀛樿褰曪紙鏁伴噺灏嗕粠 0 鎵e噺涓鸿礋鏁帮級
+ boolean allowNegative = !ObjUtil.defaultIfNull(reqDTO.getCheckFlag(), true);
+ if (allowNegative) {
+ materialStock = materialStockService.getOrCreateMaterialStock(
+ reqDTO.getItemId(), reqDTO.getWarehouseId(), reqDTO.getLocationId(), reqDTO.getAreaId(),
+ reqDTO.getBatchId(), reqDTO.getBatchCode(), reqDTO.getVendorId(), reqDTO.getReceiptTime());
+ } else {
+ throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
+ }
}
}
if (materialStock == null || materialStock.getId() == null) {
--
Gitblit v1.9.3