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 审批事件,orderId={}, 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] 销售订单不存在,orderId={}", 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 失败,saleOrderItemId={}", 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 物料信息失败,productId={}", 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 创建成功,mpsId={}, 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"));
|
}
|
|
}
|